ListView 實現定位特定 item
最近在項目中需要使 ListView 能跳轉到特定的 item,查閱文檔后,發現 ListView 有以下幾種方法可供使用:
smoothScrollToPosition(int position):平滑滾動到指定位置。如果 position 為負,則滾動到第一條;如果 position 大於 ListView item 的最大值,則滾動到最后一條。smoothScrollByOffset(int offset):平滑滾動偏移量 offset 指定的 item。如果 offset 大於 0,則表示下移;如果 offset 小於 0,則表示上移。當 offset 超過可以移動的最大值時,默認移動到頂部或尾部。setSelection(int position):直接跳轉到指定的位置,沒有任何滾動效果。setSelectionFromTop(int position,int offset):直接跳轉到指定的位置,並在Y軸設置一個偏移量。該偏移量是個 padding 值,可以用來實現類似 QQ 查看歷史消息的功能。可參考ListView的setSelection()和setSelectionFromTop()聯系
注:通過查看源代碼,其實可以發現 setSelection(int position) 其實調用的是 setSelectionFromTop(int position,int offset) 方法,只不過 offset = 0 而已。
源碼:
/**
* Sets the currently selected item. If in touch mode, the item will not be selected
* but it will still be positioned appropriately. If the specified selection position
* is less than 0, then the item at position 0 will be selected.
*
* @param position Index (starting at 0) of the data item to be selected.
*/
@Override
public void setSelection(int position) {
setSelectionFromTop(position, 0);
}
/**
* Sets the selected item and positions the selection y pixels from the top edge
* of the ListView. (If in touch mode, the item will not be selected but it will
* still be positioned appropriately.)
*
* @param position Index (starting at 0) of the data item to be selected.
* @param y The distance from the top edge of the ListView (plus padding) that the
* item will be positioned.
*/
public void setSelectionFromTop(int position, int y) {
if (mAdapter == null) {
return;
}
if (!isInTouchMode()) {
position = lookForSelectablePosition(position, true);
if (position >= 0) {
setNextSelectedPositionInt(position);
}
} else {
mResurrectToPosition = position;
}
if (position >= 0) {
mLayoutMode = LAYOUT_SPECIFIC;
mSpecificTop = mListPadding.top + y;
if (mNeedSync) {
mSyncPosition = position;
mSyncRowId = mAdapter.getItemId(position);
}
if (mPositionScroller != null) {
mPositionScroller.stop();
}
requestLayout();
}
}
簡單小Demo
MainActivity.java:
public class MainActivity extends Activity implements View.OnClickListener {
private EditText mEdt;
private Button mBtnJump, mBtnMoveUp, mBtnMoveDown;
private Button mBtnSelect;
private Button mBtnSelectPositive,mBtnSelectNagetive;
private ListView mLv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEdt = (EditText) findViewById(R.id.edt);
mBtnJump = (Button) findViewById(R.id.btn_jump);
mBtnMoveUp = (Button) findViewById(R.id.btn_move_up);
mBtnMoveDown = (Button) findViewById(R.id.btn_move_down);
mBtnSelect = (Button) findViewById(R.id.btn_select);
mBtnSelectPositive = (Button) findViewById(R.id.btn_select_from_top_positive_offset);
mBtnSelectNagetive = (Button) findViewById(R.id.btn_select_from_top_nagetive_offset);
mLv = (ListView) findViewById(R.id.lv);
mLv.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, generateString()));
mBtnJump.setOnClickListener(this);
mBtnMoveUp.setOnClickListener(this);
mBtnMoveDown.setOnClickListener(this);
mBtnSelect.setOnClickListener(this);
mBtnSelectPositive.setOnClickListener(this);
mBtnSelectNagetive.setOnClickListener(this);
}
private List<String> generateString() {
List<String> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add("item " + i);
}
return list;
}
@Override
public void onClick(View v) {
String input = mEdt.getText().toString();
int position = Integer.valueOf(input);
switch (v.getId()) {
case R.id.btn_jump:
//平滑滾動到指定位置
mLv.smoothScrollToPosition(position);
break;
case R.id.btn_move_up:
//平滑上移指定數量的item
mLv.smoothScrollByOffset(-position);
break;
case R.id.btn_move_down:
//平滑下移指定數量的item
mLv.smoothScrollByOffset(position);
break;
case R.id.btn_select:
//跳轉到指定的位置,不平移
mLv.setSelection(position);
break;
case R.id.btn_select_from_top_positive_offset:
//跳轉到指定的位置,第二個參數表示Y軸偏移量
mLv.setSelectionFromTop(position, 100);
break;
case R.id.btn_select_from_top_nagetive_offset:
//跳轉到指定的位置,第二個參數表示Y軸偏移量
mLv.setSelectionFromTop(position, -100);
break;
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.littlejie.listview.MainActivity">
<EditText
android:id="@+id/edt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入你要跳轉的行數(0~9999)"
android:inputType="number" />
<Button
android:id="@+id/btn_jump"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="點我跳轉(smoothScrollToPosition)" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_move_up"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="上移指定偏移量" />
<Button
android:id="@+id/btn_move_down"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="下移指定偏移量" />
</LinearLayout>
<Button
android:id="@+id/btn_select"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="直接跳轉到position" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_select_from_top_positive_offset"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="setSelectionFromTop(+)" />
<Button
android:id="@+id/btn_select_from_top_nagetive_offset"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="setSelectionFromTop(-)" />
</LinearLayout>
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!" />
</LinearLayout>
