AdapterView

ListViewのページ転換

ア.表示例

a.リストがスクロールする場合、先頭行を最上部に表示する位置へ移動 %{color:red}(R.id.imageButtonTop)% b.リストがスクロールする場合、前のページ分を表示する位置へ移動 %{color:red}(R.id.imageButtonPreviousPage)% c.リストがスクロールする場合、次のページ分を表示する位置へ移動 %{color:red}(R.id.imageButtonNextPage)% d.リストがスクロールする場合、最終行が最下部に評される位置へ移動 %{color:red}(R.id.imageButtonFoot)%

イ.以下の方法を参考する

①全局変数を追加する

1
2
// the position within the adapter's data set for the first item displayed on screen    
private int firstVisiblePosition = 0;

②インターフェイスOnScrollListenerを実装する

1
2
public class Main extends Activity implements OnScrollListener{
}

③メソッドonScrollStateChangedをオーバーライドする

1
2
3
4
5
6
7
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
        // Save the position that listview's top line which is visible
        firstVisiblePosition = listViewMain.getFirstVisiblePosition();
    }
}

④メソッドonPageChangedを追加する PAGE_ROWS_COUNT:ページにレコードの数 this.tabAdapter.getCount():ListViewのAdapterに全部のレコードの数

 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
private void onPageChanged(int buttonId) {
   int recordCount = this.tabAdapter.getCount();
      switch (buttonId) {
        case R.id.imageButtonTop:
          firstVisiblePosition = 0;
          break;
    case R.id.imageButtonPreviousPage:
          if (firstVisiblePosition < PAGE_ROWS_COUNT) {
            firstVisiblePosition = 0;
       } else {
           firstVisiblePosition = firstVisiblePosition - PAGE_ROWS_COUNT;
       }
          break;
        case R.id.imageButtonNextPage:
           firstVisiblePosition = PAGE_ROWS_COUNT + firstVisiblePosition;
           if (recordCount - PAGE_ROWS_COUNT < firstVisiblePosition) {
              firstVisiblePosition = recordCount - PAGE_ROWS_COUNT;
           }
           break;
        case R.id.imageButtonFoot:
           firstVisiblePosition = recordCount - PAGE_ROWS_COUNT;
           break;
        default:
           break;
       }
   if (recordCount - PAGE_ROWS_COUNT <= firstVisiblePosition) {  
        listViewMain.setSelection(recordCount);
    }
   else{
        listViewMain.setSelection(firstVisiblePosition);
    }
}

ウ.参考ソース:InDrawer841(在高登録)

ListViewのRowの特定Itemをクリック(Itemのクリックのイベント、位置計算)

Itemのクリックのイベント

①onTouch必要がある場合、Itemをクリックの位置計算方法は「特定Itemをクリックの位置計算」を参考します

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Override
public boolean onTouch(View v,MotionEvent event){
  switch(event.getAction()){
    case MotionEvent.ACTION_DOWN:
      touchedXPosition=(int)event.getX();
      touchedYPosition=(int)event.getY();
      Log.i("main",String.valueOf(touchedYPosition))
  }
  return false;
}

②onTouch必要がない場合、クリックする列に各子ビューのonClickイベントを実現する(この方法はonTouchイベントが無効になる)
ListViewAdapter:

 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
public class ListViewAdapter extends BaseAdapter {
    private final Context context;

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        TextView textView1;
        CheckedTextView textView2;
        TextView textView3;
        View view=convertView;
        if(convertView==null){
            view = inflater.inflate(layoutResourceId, parent, false);
        }
        Log.i("cash1",view.toString());
        try {
            textView1 = (TextView) view.findViewById(textViewResourceId1);
            textView2 = (TextView) view.findViewById(textViewResourceId2);
            textView3 = (TextView) view.findViewById(textViewResourceId3);
    } catch (ClassCastException e) {
        throw new IllegalStateException("ImageView/TextViewのリソースのIDが設定されていない", e);
    }

        textView1.setText(table.getTableRow().get(position).subject);
        textView2.setText(table.getTableRow().get(position).num);
        textView3.setText(table.getTableRow().get(position).subTotal);
//        test-------------------------------------↓
        final View view2=view;
        textView2.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v){
                Log.i("cash",v.getClass().toString());
                OnItemClickListener click=(OnItemClickListener) context;
                click.onItemClick((AdapterView<?>)parent,view2,position,0)
            }
        });
//        test-------------------------------------↑

MainActivityにlistViewのonItemClickイベント:

 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
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        int count=parent.getCount();
        for (int i = 0; i < count; i++) {
            if(i!=position){
                if(parent.getChildAt(i)!=null){
                    parent.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
                }
            }
        }
        //view.setBackgroundColor(Color.BLUE);
        ItemIndex=position;

        subjectText=tableTab.getTableRow().get(position).subject;
        numberText=tableTab.getTableRow().get(position).num;
        subTotalText=String.valueOf(tableTab.getTableRow().get(position).subTotal);

        //face value window
        if(popupWindowPattern==MidPopupWindowStyle.MODIFY){
            //Get the click area and object
            getClickObject();
        }
        //erase value window
        if(popupWindowPattern==MidPopupWindowStyle.ERASE){
            showPopupWindow(listViewObject,"");
        }

特定Itemをクリックの位置計算 ・画像

・listitem.xml

・ソース側

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
    /**
     * Determinant the area which is can be clicked
     */
    private void clickAreaObtain(){
        double listViewWidth=listViewObject.getWidth();
        int pointLeft=(int)(listViewWidth*(235/472d));
        int pointMiddle=(int)(listViewWidth*(275/472d));
        int pointRight=(int)(listViewWidth);

        if(pointLeft<=touchedXPosition&& touchedXPosition<pointMiddle){
            numCanBeClicked=true;
        }else{
            numCanBeClicked=false;
        }
        if(pointMiddle<=touchedXPosition&&touchedXPosition<=pointRight){
            subTotalCanBeClicked=true;
        }else{
            subTotalCanBeClicked=false;
        }
    }

ListViewのItemのデータ状態の変更説明

下記の問題はある: listviewの1つのitemを選んで、スクロールをドラッグする

これは、毎回itemに対して操作を行った後に、スクロールに転がって、選択の状態は保存していない

TableListAdapter.java

1
2
3
4
5
6
@Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked){
    String tableName;
    tableName=buttonView.getText().toString();
    DBBackupTable.setChanged(tableName,isChecked);
}

DBBackupTable.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public static void setChanged(String tableName,boolean isChecked){
    if(isChecked==true){
        if(selectTableList.contains(tableName)==false){
            selectTableList.add(tableName);
        }else{
            if(selectTableList.contains(tableName)==true){
                selectTableList.remove(tableName);
            }
        }
    }
    if(selectTableList.size()!=0){
        buttonBackupNext2.setEnabled(true);
    }else{
        buttonBackupoNext2.setEnabled(false);
    }
}

修正

毎回itemに対して操作を行った後に、選択の状態はCheckableTableNameで保存して、データを変更される

1
2
3
4
5
6
7
8
public class CheckableTableName{
    public String tableName;
    public boolean isChecked;
    public CheckableTableName(String tableName,boolean isChecked){
        this.tableName=tableName;
        this.isChecked=isChecked;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@Override
public void onClick(View v){
   checkBox checkBox=(CheckBox)v;
   CheckableTableName checkedTableName=(CheckableTableName)getItem(position);
    checkedTAbleName.isChecked=checkBox.isChecked();
    if(context instanceof CheckBoxChangeable){
        CheckBoxChangeable result=(CheckBoxChangeable) context;
        result.onCheckBoxStatusChanged(hasItemChecked());
    }
}
@Override
public Object getItem(int position){
   return tableNameList.get(position);
}

ListViewのデータオブジェクトのアドレス/再びBindingRefresh

①、初期化で下記のコーディングがあります。

1
2
3
4
private EjReader ejReader;
private ListViewAdapter listViewAdapter;
private List<EjHeaderList> ejHeaderLists;
private PageListView listViewHead;

②、ListViewのデータのBinding

1
2
3
4
ejHeaderLists = ejReader.getHeaderList(enterDate);
listViewAdapter = new ListViewAdapter(this, ejHeaderLists,
R.layout.list_view, R.id.textViewHead, PAGE_ROWS_COUNT);
listViewHead.setAdapter(listViewAdapter);

③、ListViewのデータが変更されたので、臨時変数(tempEjHeadList)を利用し、データを取得した、また、変数(ejHeadLists)をクリアし、臨時変数(tempEjHeadList)のデータは変数(ejHeadLists)を与えます。システム関数「.notifyDataSetChanged()」を利用し、ListViewのデータ再Binding、データを表示する。

1
2
3
4
5
6
7
List<EjHeaderList> tempEjHeaderLists = ejReader.getHeaderList(enterDate.getDate());
ejHeaderLists.clear();
for (EjHeaderList item : ejHeaderListsTemp) {
    ejHeaderLists.add(item);
}
listViewAdapter.setSelectingPosition(-1);
listViewAdapter.notifyDataSetChanged();

ListViewのItemに異なる構造を表示する

表示の効果

右側listviewの中で、3種類の異なる構造がある

実現の方法 listitem.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
32
33
34
35
36
37
38
39
    <LinearLayout
        android:id="@+id/linearLayoutUp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical" >

        <TextView
            android:id="@+id/textViewItemNameUp"
            style="@style/reaervation_style_listview_textview"
            android:layout_width="107px"
            android:layout_marginLeft="5px"
            android:gravity="center_vertical"
            android:text="TextView" />

        <RelativeLayout
            android:id="@+id/layoutItemValueUp"
            android:layout_width="250px"
            android:layout_height="match_parent" >

            <jp.co.casio.caios.component.casiosoft.view.AutoSizeTextView
                android:id="@+id/textViewItemValueUp"
                style="@style/reaervation_style_listview_textview"
                android:layout_width="245px"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginLeft="5px"
                android:gravity="center_vertical"
                android:text="TextView" />

            <TextView
                android:id="@+id/textViewItemValueTimeSlot"
                style="@style/reaervation_style_listview_textview"
                android:layout_width="wrap_content"
                android:layout_alignParentRight="true"
                android:gravity="center_vertical"
                android:text="TextView"
                android:visibility="invisible" />
        </RelativeLayout>
    </LinearLayout>

 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
    <LinearLayout
        android:id="@+id/linearLayoutCenter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical" >

        <TextView
            android:id="@+id/textViewItemNameTitle"
            style="@style/reaervation_style_listview_textview"
            android:layout_width="300px"
            android:layout_height="30px"
            android:layout_marginBottom="3px"
            android:layout_marginLeft="5px"
            android:gravity="bottom|center_horizontal"
            android:text="" />

        <TextView
            android:id="@+id/textViewItemQtyTitle"
            style="@style/reaervation_style_listview_textview"
            android:layout_width="55px"
            android:layout_height="30px"
            android:layout_marginBottom="3px"
            android:layout_marginLeft="5px"
            android:gravity="bottom|center_horizontal"
            android:singleLine="true"
            android:text="" />
    </LinearLayout>

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
    <LinearLayout
        android:id="@+id/linearLayoutDown"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical" >

        <TextView
            android:id="@+id/textViewItemTradeName"
            style="@style/reaervation_style_listview_textview"
            android:layout_width="300px"
            android:layout_marginLeft="5px"
            android:gravity="center_vertical"
            android:text="TextView" />

        <TextView
            android:id="@+id/textViewItemQty"
            style="@style/reaervation_style_listview_textview"
            android:layout_width="50px"
            android:layout_marginLeft="5px"
            android:gravity="right|center_vertical"
            android:text="TextView" />
    </LinearLayout>

3種類の構造は1つの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
 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
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
    View view = convertView;
    if (convertView == null) {
        view = inflater.inflate(R.layout.list_item_right, parent, false);
    }
        LinearLayout upLayout;
    LinearLayout centerLayout;
    LinearLayout downLayout;
//三つ部分のレイアウトを取得する。
    upLayout = (LinearLayout) view.findViewById(R.id.linearLayoutUp);
    centerLayout = (LinearLayout) view.findViewById(R.id.linearLayoutCenter);
    downLayout = (LinearLayout) view.findViewById(R.id.linearLayoutDown);
        if (0 <= position && position <= getCount() - 22) {
        getUpView(upLayout, centerLayout, downLayout, view, parent, position);
    }
        if (position == getCount() - 21) {
        getCenterView(upLayout, centerLayout, downLayout, view, parent, position);
    }
        if (getCount() - 21 < position && position <= getCount() - 1) {
        getDownView(upLayout, centerLayout, downLayout, view, parent, position);
    }
        return view;
}
private void getUpView(LinearLayout upLayout, LinearLayout centerLayout, LinearLayout downLayout,
          View view,final ViewGroup parent, final int position) {
    TextView textViewItemNameUp;
    AutoSizeTextView textViewItemValueUp;
    TextView textViewItemValueTimeSlot;
    RelativeLayout layoutItemValueUp;
    try {
        layoutItemValueUp = (RelativeLayout) view.findViewById(R.id.layoutItemValueUp);
        textViewItemNameUp = (TextView) view.findViewById(R.id.textViewItemNameUp);
        textViewItemValueUp = (AutoSizeTextView) view.findViewById(R.id.textViewItemValueUp);
        textViewItemValueTimeSlot = (TextView) view.findViewById(R.id.textViewItemValueTimeSlot);
    } catch (ClassCastException e) {
        throw new IllegalStateException("ERROR", e);
    }
    final View view2 = view;
    Cell cell = (Cell) getItem(position);
    textViewItemNameUp.setText(cell.getCaption());
    textViewItemValueUp.setText(cell.getDispValue());
//フィルドは「使用時間」時、開始時間と終了時間を合併で表示する
    if (cell.getColumnName().equals(MasterDB.FIELD_USETIME)) {
        textViewItemValueUp.setWidth(PX_WIDTH_100);
        String startTime = row.getCell(MasterDB.FIELD_USEDATE).getValue() + row.getCell(MasterDB.FIELD_USETIME).getValue();
        String endTime = row.getCell(MasterDB.FIELD_ENDTIME).getValue();
        Res res = new Res(context);
        String timeSlot = res.getTimeSlot(startTime, endTime);
        textViewItemValueTimeSlot.setText(timeSlot);
        textViewItemValueTimeSlot.setVisibility(View.VISIBLE);
    } else {
        textViewItemValueUp.setWidth(PX_WIDTH_245);
        textViewItemValueTimeSlot.setVisibility(View.INVISIBLE);
    }

    layoutItemValueUp.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            OnItemClickListener click = (OnItemClickListener) context;
            click.onItemClick((AdapterView<?>) parent, view2, position, R.id.layoutItemValueUp);
        }
    });
//upLayoutを処理する場合、upLayoutだけを可視にする
    upLayout.setVisibility(View.VISIBLE);
    centerLayout.setVisibility(View.INVISIBLE);
    downLayout.setVisibility(View.INVISIBLE);
//upLayoutを処理する場合、第一明細行の上罫線は可視とする、中央の明細部の下罫線は不可視とする、最後の明細部は下罫線も不可視、そして、高さも違うとする
    if (position == 0) {
        view.setBackgroundResource(R.drawable.bgupfirst);
    } else if (position == getCount() - 22) {
        view.setBackgroundResource(R.drawable.bguplast);
    } else {
        view.setBackgroundResource(R.drawable.bgup);
    }
}
private void getCenterView(LinearLayout upLayout, LinearLayout centerLayout, LinearLayout downLayout, View view,
    final ViewGroup parent, int position) {
    TextView textViewItemNameTitle;
    TextView textViewItemQtyTitle;
    try {
        textViewItemNameTitle = (TextView) view.findViewById(R.id.textViewItemNameTitle);
        textViewItemQtyTitle = (TextView) view.findViewById(R.id.textViewItemQtyTitle);
    } catch (ClassCastException e) {
        throw new IllegalStateException("ERROR", e);
    }
    Cell cell = (Cell) getItem(position);
    textViewItemNameTitle.setText(cell.getCaption());
    textViewItemQtyTitle.setText(cell.getDispValue());
//centerLayoutを処理する場合、centerLayoutだけを可視にする
    upLayout.setVisibility(View.INVISIBLE);
    centerLayout.setVisibility(View.VISIBLE);
    downLayout.setVisibility(View.INVISIBLE);
    view.setBackgroundResource(R.drawable.bg);
}
private void getDownView(LinearLayout upLayout, LinearLayout centerLayout, LinearLayout downLayout, View view,
        final ViewGroup parent, final int position) {
    TextView textViewItemTradeName;
    TextView textViewItemTradeNumber;
    try {
        textViewItemTradeName = (TextView) view.findViewById(R.id.textViewItemTradeName);
        textViewItemTradeNumber = (TextView) view.findViewById(R.id.textViewItemQty);
    } catch (ClassCastException e) {
        throw new IllegalStateException("ERROR", e);
    }
    final View view2 = view;
    Cell cellItemCode = (Cell) getItem(position);
    Cell cellItemQty = (Cell) getItem(position + 20);
    textViewItemTradeName.setText(cellItemCode.getDispValue());
    if (TextUtils.isEmpty(cellItemCode.getValue()) == false) {
        textViewItemTradeNumber.setText(cellItemQty.getDispValue());
    } else {
        textViewItemTradeNumber.setText("");
    }
//downLayoutを処理する場合、downLayoutだけを可視にする
    upLayout.setVisibility(View.INVISIBLE);
    centerLayout.setVisibility(View.INVISIBLE);
    downLayout.setVisibility(View.VISIBLE);
    textViewItemTradeName.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            OnItemClickListener click = (OnItemClickListener) context;
            click.onItemClick((AdapterView<?>) parent, view2, position, R.id.textViewItemTradeName);
        }
    });
    textViewItemTradeNumber.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            OnItemClickListener click = (OnItemClickListener) context;
            click.onItemClick((AdapterView<?>) parent, view2, position, R.id.textViewItemQty);
        }
    });
//downLayoutを処理する場合、downLayout明細の第一明細行は上の罫線を可視にする、最後の行は下の罫線を可視にする
    if (position == getCount() - 1) {
        view.setBackgroundResource(R.drawable.bgdownlast);
    } else {
        view.setBackgroundResource(R.drawable.bgdown);
    }
}

ListViewの高速スクロールバー

①リストビューのファストスクロールバー: 下記のように「fastScrollEnabled」=true(使用可能)と「fastScrollAlwaysVisible」=true(可視)を設定する

1
2
3
4
5
6
7
8
9
<ListView
    android:id="@+id/listViewLink"
    android:divider="#000000"
    android:fadingEdge="none"
    android:fastScrollEnable="true"
    android:fastScrollAlwaysVisible="true"
    android:layout_height="match_parent"
    android:layout_width="match_parent">
</ListView>

②リストビューのitem数が4ページ以上のみ、ファストスクロールバーを表示する場合、下記のように設定する。 xmlで「fastScrollEnable」と「fastScrollAlwaysVisible」を設定しないでください xxx.java:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
private void setFastScrollVisible(){
 ListView listViewLink =(ListView)findViewById(R.id.listViewLink);
//高速スクロールバーを使用する
 listViewLink.setFastScrollEnabled(true);
 if(4<=pageLinks.list().size()){
   //高速スクロールバーを表示する
    listViewLink.setFastScrollAlwaysVisible(true);
 }else{
   //高速スクロールバーを表示しない
    listViewLink.setFastScrollAlwaysVisible(false);
  }
}

ListViewのitemをドラッグできる(DragListView)

ListViewにitemがドラッグを実現する

アイテムを上下に入れ替えることになりましたが、移動の操作とスクロールの操作は衝突があるので、アイテムを長押し(ロングタップ)して選択状態とし、ドラッグする

1
2
3
4
5
6
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
        int position, long id) {
    listViewTag.onLongClick();
    return false;
}

クラス「ArrayAdapter」から、子クラスを実装して、必要実装するメソッドはBaseAdapterと同じ

1
2
3
4
public class TagAdapter extends ArrayAdapter<Tag>{
  private List<Tag>listTag;
  private final LayoutInflater inflater;
}

自分でListViewクラスを実装する方法 「onInterceptTouchEvent」と「onTouchEvent」はオーバーライド必要です 1.ListViewにドラッグするitemを取得する

 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
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    boolean result = super.onInterceptTouchEvent(ev);
    if (enableDrag == false) {
        return result;
    }
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        x = (int) ev.getX();
        y = (int) ev.getY();
//dragSrcPosition:ドラッグするitemの元位置 
//dragPosition:リストの中に該当ドラッグitemとする項目の位置
        dragSrcPosition = dragPosition = pointToPosition(x, y);
        TagAdapter adapter = (TagAdapter) getAdapter();
        if (dragPosition == AdapterView.INVALID_POSITION || dragSrcPosition == 0 || dragSrcPosition == adapter.getCount() - 1) {
            return result;
        }
//itemView(ViewGroup):ListViewにドラッグするitem
//dragPoint:リストと相対的位置
//dragOffset:縦向きの移動量
        itemView = (ViewGroup) getChildAt(dragPosition - getFirstVisiblePosition());
        dragPoint = y - itemView.getTop();
        dragOffset = (int) (ev.getRawY() - y);
        result = false;
    }
    return result;
}

2.ドラッグ開始前、ドラッグする対象の映像を生成する

 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
/**
 * 移動開始前、移動対象を生成する
 */
public void onLongClick() {
    if (itemView != null) {
//upScrollBounce:ドラッグする場合、スクロールの上限界
//downScrollBounce:ドラッグする場合、スクロールの下限界
        upScrollBounce = Math.min(y - scaledTouchSlop, getHeight() / 3);
        downScrollBounce = Math.max(y + scaledTouchSlop, getHeight() * 2 / 3);
//ドラッグするitemのビットマップを得る
        itemView.setDrawingCacheEnabled(true);
        Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
        startDrag(bm, y);
    }
}

/**
 * 移動前移動対象のイメージを初期化
 * 
 * @param bm
 *            移動対象のイメージを渡す  
 * @param y
 *            移動対象の開始位置を初期化
 */
public void startDrag(Bitmap bm, int y) {
    stopDrag();
//映像が表示の位置を設定する↓
    windowParams = new WindowManager.LayoutParams();
    windowParams.gravity = Gravity.TOP | Gravity.LEFT;
    windowParams.x = x;
    windowParams.y = y - dragPoint + dragOffset;
    windowParams.width = android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
    windowParams.height = android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
    windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
            | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
    windowParams.format = PixelFormat.TRANSLUCENT;
    windowParams.windowAnimations = 0;
//映像が表示の位置を設定する↑

//ドラッグするitemの映像が画面に追加する↓
    ImageView imageView = new ImageView(getContext());
    imageView.setImageBitmap(bm);
    windowManager = (WindowManager) getContext().getSystemService(WINDOW);
    windowManager.addView(imageView, windowParams);
//ドラッグするitemの映像が画面に追加する↑
    dragImageView = imageView;
}

3.itemをドラッグする

 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
/**
 * タッチ事件
 */
@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (dragImageView != null && dragPosition != INVALID_POSITION) {
        int action = ev.getAction();
        int evY = (int) ev.getY();
        switch (action) {
        case MotionEvent.ACTION_UP:
            stopDrag();
//ドラッグ完了して、ListViewのアイテムはこのメソッドに保存する
            onDrop(evY);
            ((OnLongFragmentItemClickListener) obj).onLongFragmentItemClick();
            break;
        case MotionEvent.ACTION_MOVE:
//ドラッグするitem
            onDrag(evY);
            break;
        default:
            break;
        }
        return true;
    }
    return super.onTouchEvent(ev);
}

/**
 * Moveメソッドで以下のソースを実行する
 * 
 * @param y
 */
public void onDrag(int y) {
//itemの映像がドラッグする↓
    if (dragImageView != null) {
        windowParams.alpha = 0.8f;
        windowParams.y = y - dragPoint + dragOffset;
        windowManager.updateViewLayout(dragImageView, windowParams);
    }
//itemの映像がドラッグする↑
    // 限界線に移動する場合、-1の戻るを避ける
//ドラッグの 限界を制御するように、移動限界が越えって、-1の戻るを避ける↓
    int tempPosition = pointToPosition(0, y);
    if (tempPosition != INVALID_POSITION) {
        dragPosition = tempPosition;
    }
//ドラッグの 限界を制御するように、移動限界が越えって、-1の戻るを避ける↑
    // スクロール
    int scrollHeight = 0;
    if (y < upScrollBounce) {
        scrollHeight = MOVE_UP_DIP;// 上にスクロール可能であれば、上に8個dipを移動する
    } else if (y > downScrollBounce) {
        scrollHeight = MOVE_DOWN_DIP;// 下にスクロール可能であれば、下に8個dipを移動する
    }
    if (scrollHeight != 0) {
//ドラッグするitemの位置は画面に越えるの場合、ListViewはスクロールを実行する↓
        // スクロールを実現するメソッド
        int childTop = getChildAt(dragPosition - getFirstVisiblePosition()).getTop();
        setSelectionFromTop(dragPosition, childTop + scrollHeight);
//ドラッグするitemの位置は画面に越えるの場合、ListViewはスクロールを実行する↑
    }
}

4.ドラッグを止まる

 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
/**
 * 移動を中止、移動対象のイメージを削除
 */
public void stopDrag() {
    if (dragImageView != null) {
//画面にドラッグitemの映像は削除する
        windowManager.removeView(dragImageView);
        dragImageView = null;
    }
}

/**
 * タッチ終わり場合拖动放下的时候
 * 
 * @param y
 */
pubic void onDrop(int y) {
    // 限界線に移動する場合、-1の戻るを避ける
    int tempPosition = pointToPosition(0, y);
    if (tempPosition != INVALID_POSITION) {
        dragPosition = tempPostion;
    }
//移動の位置を制御する↓
    // 限界を超える場合の処理
    if (y < getChildAt(1).getTop()) {
        // 上限界を超える
        dragPosition = 1;
    } else if (y > getChildAt(getChildCount() - 1).getBottom()) {
        // 下限界を超える
        dragPosition = getAdapter().getCount() - 1;
    }
//移動の位置を制御する↑
    updateTagList();
}

/**
 * データを配置
 * 
 * @param offset
 */
private void updateAdapter(int dragSrcPosition, int offset) {
    TagAdapter adapter = (TagAdapter) getAdapter();
//itemの位置を交換する
    Tag tag = (Tag) adapter.getItem(dragSrcPosition);
    adapter.remove(tag);
    adapter.insert(tag, offset);
}

ListViewのItemViewに背景設定の不順調について

参照ソース:"ここへ":http://czuft-redmine:3000/projects/vx100/repository/revisions/12744

上記の画面通り、Listviewのアイテムをクリックすると、背景イメージを設定することがありますが そのとき、ほかの行をClick downして上、下の方向にスペード速くてドラッグすると、 下記の不順調が発生するかもしれないのです。

原因としては、究明しました。 AdapterのgetViewにて、直接的にviewのメソッドで背景色設定を行ってしまったのです。

上記のviewに対してのメソッドを使うのは危ないので退避してください。 ListviewのItemレイアウト定義ファイルで

  • 背景色設定レイアウトを用意します

1
2
3
4
5
6
7
    <LinearLayout
        android:id="@+id/layoutShadow"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/common_row_bg"
        android:orientation="horizontal"
        android:visibility="invisible" />
  • AdapterのgetViewに表示するかどうかを抑制するように

【注意】

  • 今回のListViewのItemレイアウトでは、複雑なので項目の数も多くて、効率的に %{color:red}ViewHolder% を使うように統一してください。 "ViewHolderの説明":http://czuft-redmine:3000/projects/documents/wiki/Adapter%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9#5子ビューへのアクセスを高速化

  • 背景色のLayoutBarについてですが、

  • XMLレイアウトの先頭に移動して統一してください。
  • FrameLayoutからLinearLayoutに変更してください。

GetViewが頻繁に呼び出されています

  • adapterにgetviewが頻繁に呼び出されている場合、下記の内容を検査してください

1.GridViewまたはListViewの複数選択のプロパティを設定される

1
2
3
4
5
6
7
8
9
<!--  プロパティ[choiceMode]は「none」以外の値を設定すると、itemを選択して、getViewが呼び出されています -->
 <GridView
     android:id="@+id/gridViewPage"
     style="@style/style_grid_list_view"
     android:choiceMode="multipleChoice"
     android:layout_margin="20dp"
     android:horizontalSpacing="20dp"
     android:verticalSpacing="20dp" >
 </GridView>  

2.GridViewまたはGridViewのparentの「height」は「wrap_content」

1
2
3
4
5
6
7
8
9
<!--  左画面の設定値を避けすれば、layout_heightは以下の設定を使う:「wrap_content」→「fill_parent」/固定の値 -->
 <GridView
     android:id="@+id/gridViewPage"
     android:layout_height="wrap_content"
     style="@style/style_grid_list_view"
     android:layout_margin="20dp"
     android:horizontalSpacing="20dp"
     android:verticalSpacing="20dp" >
 </GridView>  

3.GridViewのparentは「RelativeLayout」

GridViewのparentは「RelativeLayout」の場合、一つ「RelativeLayout」があって、getViewは二つ呼び出す それで、レイアウトにできるだけ「LinearLayout」または「AbsoluteLayout」を使用してください。

GridViewに罫線を追加する

ア.効果図:

イ.以下の方法を参考する

①、res/layout/下にXMLファイルを定義する

grid_view_file_item_thumbnail.xml

1
2
3
4
5
6
7
8
9
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/layoutGridItem"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:background="@drawable/grid_line"
 android:orientation="vertical" >
 <!-- Cell contents -->
 </RelativeLayout>

②、res/drawable/下にXMLファイルを定義する

grid_line.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/item_border"/>
    <item
        android:bottom="1dp"
        android:drawable="@drawable/item_inner"
        android:left="0dp"
        android:right="1dp"
        android:top="0dp"/>
</layer-list>

item_border.xml

1
2
3
4
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#FF404040"/>
</shape>

item_inner.xml

1
2
3
4
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#FF333333" />
</shape>

ExpandableListView