View関連

View部品の作成と使用方法

  • View部品の作成と使用方法は下記の例として、説明します。

  • ①、xmlファイル「view_enter_date.xml」を作成し、下記のレイアウトとコーディングです。

  • レイアウト

  • コーディング

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:weightSum="29">
    <TextView
  android:id="@+id/textViewEnterDate"
  android:layout_weight="19"
  android:text="9999/99/99"
  android:layout_height="match_parent"
  android:layout_width="315dp"
  android:gravity="center"
  android:textSize="30sp"></TextView>
    <LinearLayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:gravity="center"
  android:layout_weight="10">
  <Button
      android:id="@+id/buttonPreviousDay"
      android:layout_height="match_parent"
      android:layout_width="match_parent"
      android:layout_weight="0.5"></Button>
  <Button
      android:id="@+id/buttonNextDay"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_weight="0.5"></Button>
    </LinearLayout>
</LinearLayout>
  • ②、パッケージ「jp.co.casio.caios.casiosoft.framework.logic.view」を作成し、クラス「EnterDate.java」を作成する。

クラス「EnterDate.java」で部品の機能を実施する。

  • ③、部品使用方法:

xmlファイルで下記のように記入します。

1
2
3
4
 <jp.co.casio.caios.casiosoft.framework.logic.view.EnterDate
     android:layout_width="wrap_content"
     android:layout_height="match_parent"
     android:id="@+id/enterDate" />

呼び出すActivityでは、インタフェース「OnEnterDateChangedListener」を実装する必要がある

1
2
 public class Mailn extends Activity implements OnClickListener,
  OnItemClickListener, OnEnterDateChangedListener, OnScrollListener {......

上記のA~Eのボタン、ウィンドタイトルの表示文字を設定する。

1
2
3
4
EnterDate enterDate = (EnterDate) findViewById(R.id.xxxxxx);
  enterDate.setButtonText(previousDate, nextDate);         //A、Bのテキストを設定する
  enterDate.setDialogTitle(dialogTitle);   //Cのタイトルを設定する
  enterDate.setDialogButtonText(dialogButtonLeft, dialogButtonRight);  //D、Eのテキストを設定する

Overrideのメソッドで細かい処理を行います。

1
2
3
4
5
@Override
 public void onEnterDateChanged(int year, int monthOfYear, int dayOfMonth) {
 ......
//細かい処理
 }

ViewのHint と他のプロパティーの混合設定

  • ViewのHint と他のプロパティーの混合設定する場合、下記の内容を注意してください。 *

■Hint 、Gravity、 InputType 同時設定するときに、android:ellipsize="start"を設定すべき

Viewの半透明化

Viewの半透明化になるように、FrameLayoutを利用する。 |{background:#CCFFFF;padding:50px}.FrameLayout|

この部分にいろいろなビュー(レイアウト、コントロールなど)がある 上記のレイアウトを半透明したい時に、下記のメソッドの実現方法を参照してください

1
2
3
4
5
6
7
8
private void createCover(FrameLayout layout){
    TextView textView=new TextView(AdvertiseActivity.this);
    //TextViewで渡したLayoutを覆う
    textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.FILL_PARENT));
    //TextViewのカラーとアルファ(AARRGGBB)を設定する
    textView.setBackgroundColor(Color.parseColor("#86222222"));
    layout.addView(textView);
}

半透明化の実行効果

二つViewのBinding<Point>

ア.表示例

View1(行をクリックするによって、view1を移動する)

View2

イ.facevaluepopup.xml

ウ.View1の上下に移動する
メソッドsetPaddingを使用する

複数個Viewは同時連動する

同時に転がってscrollTo を使います, scrollBy を使います恐らく無限ループに陥ります。 下の例は

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    /**
     * Show the Face Value window
     */
    public void showPopupWindow(){
  //set pointer.png position
  ImageView imageViewPopPoint=(ImageView) view .findViewById(R.id.imageViewPopPoint);
  //view1
  imageViewPopPoint.setPadding(imageViewPopPoint.getPaddingLeft(),
imageViewPopPoint.getPaddingTop()+this.pointerTop;
  imageViewPopPoint.getPaddingRight(),
  imageViewPopPoint.getPaddingBottom());
  textViewOld.setText(this.clickItemSubToatalText);
  //show popupWindow
  //view2
  pw=new PopupWindow(view,this.popWidth,this.popHeight,true);
  pw.showAtLocation(this.parentView,Gravity.RIGHT,this.offsetX,this.offsetY);
    }

    @Override
    public boolean onTouch(View v,MotionEvent event){
  switch(event.getAction()){
  case MotionEvent.ACTION_DOWN:
      touchedXposition=(int)event.getX();
      //this.pointerTop:ItemのクリックのY軸位置
      touchedYposition=(int)event.getY();
      Log.i("main",String.valueOf(touchedYPosition));
  }
  return false;
    }

システムは同一アドレスのビューを再び設定でエラー発生すること

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
    alertDialog =new AlertDialog.Builder(context).create();
    alertDialog.setView(getLayoutInflater().inflater(R.layout.dialog_input,null));
    alertDialog.show();
    //Get hte view of the showing alertDialog
    View view =alertDialog.getWindow().getDecorView();
    alertDialog.setContentView(getLayoutInfalter().inflate(R.layout.dialog_input,null));
 ```

上記のソースの中で同じ部分 +getLayoutInflater().inflate(R.layout.dialog_input,null)+ は見えるソースを重複に書くことを避けるために下記のソースBに変える

```java
    alertDialog = new AlertDialog.Builder(context).create();
    View v = getLayoutInflater().inflate(R.layout.dialog_input, null);
    alertDialog.setView(v);
    alertDialog.show();
    // Get hte view of the showing alertDialog
    View view = alertDialog.getWindow().getDecorView();
    alertDialog.setContentView(v);
 ```

しかしBソースを運行すれば異常は出す

![](img/8.1.jpg)

この異常の内容は親ビューは既に存在する場合親ビューを二度と追加できない
こちらで疑問があるどしてソースAを運行する場合異常は出さない調査を試してみて原因は下記の通り

```java
    alertDialog = new AlertDialog.Builder(context).create();
    alertDialog.setView(getLayoutInflater().inflate(R.layout.dialog_input, null));
    System.out.println(getLayoutInflater().inflate(R.layout.dialog_input, null));
    alertDialog.show();
    // Get hte view of the showing alertDialog
    View view = alertDialog.getWindow().getDecorView();
    alertDialog.setContentView(getLayoutInflater().inflate(R.layout.dialog_input,null));;
    System.out.println(getLayoutInflater().inflate(R.layout.dialog_input,null));
 ```

このソースの印刷結果は下記のとおり

* System.out android.widget.AbsouluteLayout@44f5cf30
* System.out android.widget.AbsouluteLayout@44f66180%

エラー原因は
ソースAでsetViewで設定するビューとsetContentViewで設定するビューの物理アドレスは違うシステムは二つビューのような処理するのでエラーは出さない
ソースBで同一ビューを使用するため物理アドレスは同じとするのでエラーは出さる

## Spinnerの使用

Spinnerの使用  
①1つのadapterを新たに作ります

 ```java
class SpinnerAdapter extends BaseAdapter {
       private LayoutInflater inflater;
       private List<Tag> listTag;
       private CommonTag commonTag;
       private Context context;
       public SpinnerAdapter(Context context, List<Tag> listTag) {
     inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     this.context = context;
     this.listTag = listTag;
     commonTag = new CommonTag();
     }
     @Override
     public int getCount() {
      return listTag.size();
      }
  @Override
  public Object getItem(int position) {
      return listTag.get(position);
      }
  @Override
  public long getItemId(int position) {
      return position;
      }
  public View getView(int position, View convertView, ViewGroup parent) {
      View view = convertView;
      if (convertView == null) {
       //R.layout.dialog_spinner_itemのレイアウトソースはA部分に示す
      }
      view = inflater.inflate(R.layout.dialog_spinner_item, parent, false);
      }
      Resources res = context.getResources();
      Drawable tagIcon = null;
      int keyColor = listTag.get(position).getColor();
      TextView textViewtextViewName = (TextView) view.findViewById(R.id.textViewSpinnerName);
      textViewtextViewName.setText(listTag.get(position).getName());
      tagIcon = res.getDrawable(commonTag.getBigIntTag(keyColor));
      if (tagIcon != null) {
tagIcon.setBounds(0, 0, tagIcon.getMinimumWidth(), tagIcon.getMinimumHeight());
      textViewtextViewName.setCompoundDrawables(tagIcon, null, null, null);
      }
return textViewtextViewName;
      }
}
 ```

A部分

```xml
<TextView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/textViewSpinnerName"
  android:layout_width="525dp"
  android:layout_height="48dp"
  android:textColor="@android:color/black"
  android:gravity="left|center_vertical"
  android:textSize="18dp" 
  />
 ```

②実例adapter

 ```java
spinnerAdapter = new SpinnerAdapter(context, spinnerListTag);
spinner.setAdapter(spinnerAdapter);
 ```

XML

```xml
<Spinner
  android:id="@+id/spinner"  
  android:layout_width="525dp"  
  android:layout_height="48dp"  
  android:layout_x="105dp"  
  android:layout_y="60dp"  
  android:background="@drawable/dialog_btn_tag_edit_form_on"  
  android:popupBackground="@drawable/dialog_btn_tag_edit_form"  
  />  
 ```

## Calendarを使用するの問題

JAVAにクラスCalendarを使用する場合注意点がある

* Calendarの月は1月から12月までではない0月から11月までとするべき

```java
Calendar calendar=Calendar.getInstance();
calendar.set(Calendar.YEAR,2012);
calendar.set(Calendar.MONTH,3);//[3]は4-1の結果とする
calendar.set(Calendar.DATE,24);
  1. ギャラリーで選択したインメージを居中な表示したくない場合、ギャラリーのメソッドOnItemClickを実現するが、OnItemSelectedを実現しない。 そしてギャラリークラスを継承して、onSingleTapUp方法を実現する。
1
2
3
4
5
6
@Override
public boolean onSingle(final MotionEvent e){
    boolean handled=super.onSingleTapUp(e);
    onDown(e);
    return handled;
}
  1. ギャラリーの位置を設定すると余白を削除する

①位置を設定する

②setSelection方法を実現する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * アイテムを選択
 * @param position 選択されたアイテムのポジション
 */
@Override
public void setSelection(int position) {
        if (mPageCount == 0) {
        super.setSelection(position);
        return;
    }
    int pos = position;
    int lastIndex = 0;
    if (getAdapter() != null) {
        lastIndex = getAdapter().getCount() - 1;
    }
    int lastPageFirstIndex = Math.max(0, lastIndex - mPageCount + 1);
    int pageFirstVisiblePosition = getLastVisiblePosition() - mPageCount
            + 1;
    if (mPageLastVisiblePosition - mPageCount + 1 <= position) {
    if (position < mPageCount && pageFirstVisiblePosition <= position) {
            pos = 0;
        } else if (lastPageFirstIndex <= position
                && position <= getLastVisiblePosition()) {
        pos = lastPageFirstIndex;
        } else if (getLastVisiblePosition() < position
                || mPageLastVisiblePosition + 1 < position) {
        pos = position - mPageCount + 1;
        } else if (position < pageFirstVisiblePosition) {
            pos = getLastVisiblePosition() - mPageCount;
        } else {
            pos = position - mPageCount / HALF;
        }
    }
    pos = Math.max(0, pos);
    super.setSelection(pos);
    }

③以下の通りメソッドを実現する

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
 *ページ選択領域の幅を取得、 gallery初期化時、位置を設定する
 */
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    mPageLastVisiblePosition = getLastVisiblePosition();
    if (mLayoutWidth == 0) {
        mLayoutWidth = r;
        computeFirstTimeAndLink(true);
        setSelection(getSelectedItemPosition());
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    int action = event.getAction();
    if (action == MotionEvent.ACTION_DOWN) {
        scrollToRight = false;
    }
    return super.onTouchEvent(event);
}
/*
 *頁の表示を左・右に移動します
 */

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
        float velocityY) {
    if (MAX_SPACING < e1.getX() - e2.getX()) {
        scrollToRight = true;
    }
    return super.onFling(e1, e2, velocityX, velocityY);
}
/*
 *itemの表示を左・右に移動します
 */
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
        float distanceY) {
    if (MAX_SPACING < e1.getX() - e2.getX()) {
        scrollToRight = true;
    }
    return super.onScroll(e1, e2, distanceX, distanceY);
}
/**
 *  スクロールし終わった後の処理 → 右端まで行ったとき
 */
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    mPageLastVisiblePosition = getLastVisiblePosition();
    int lastIndex = 0;
    if (getAdapter() != null) {
        lastIndex = getAdapter().getCount() - 1;
    }
    if (getLastVisiblePosition() == lastIndex && scrollToRight) {
        int firstIndex = Math.max(0, lastIndex - mPageCount + 1);
        super.setSelection(firstIndex);
    }
    super.onScrollChanged(l, t, oldl, oldt);
}
  1. もしギャラリーで選択したインメージを居中に表示して,そしてギャラリー横向きスクロールする場合、中央のインメージのサムネイルを表示しない ギャラリーでonItemSelectedメソッドをオーバーライドする、そしてスレッドでコントロールする
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
    pages.unselect();
    if (isFirstSelected == true) {
        isFirstSelected = false;
        position = pages.getCurrentId();
    }
    ((Gallery) findViewById(R.id.galleryPageShow)).setSelection(position);
    pages.select(position);
    toShowIndex = position;
//スレッドで中央のサムネールの表示をコントロールする
    final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (showingIndex != toShowIndex) {
                showingIndex = toShowIndex;
                galleryImageAdapter.notifyDataSetChanged();
                updateCurrentPage();
            }
        }
    };

    Thread checkChange = new Thread() {
        @Override
        public void run() {
            int myIndex = toShowIndex;
            try {
                sleep(TIME_OUT_DISPLAY);
                if (myIndex == toShowIndex) {
                    handler.sendEmptyMessage(0);
                    Log.v("test", "+++ stable can show ...");
                } else {
                    Log.v("test", "+++ not stable...");
                }
            } catch (InterruptedException e) {
                    e.printStackTrace();
            }
        }
    };
    checkChange.start();
}