想要實現一個listview初始化時和數據變化後顯示到列表的最末,簡單地說就是像聊天窗或者是日誌輸出那樣的情景。
開始沒去仔細看listview對象的屬性,按照慣性思維就去 調用 listView.scrollTo(offset_x,offset_y);
然後又被一篇奇怪的日誌誤導了什麼外層容器和 內層兩個view …幹!浪費我時間。
其實listView元素直接在xml裏就可以簡單定義實現好這個效果,附帶實現的方法三個。
方法1:直接在layout裏對listView的屬性定義
StackFromBottom: true
Transcript Mode: alwayScroll
方法2: 把上面的方法改爲java代碼的方式聲明
listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
listView.setStackFromBottom(true);
方法3: 變通的做法 把焦點focus去listView的最後一個item,那自然就是顯示最底部
每次適配器 adapter.notifyDataSetChanged() 之後要記得調用,略麻煩
注意要用 post的方法確保listview的數據已經加載完畢
private void scrollMyListViewToBottom() {
listView.post(new Runnable() {
@Override
public void run() {
// Select the last row so it will scroll into view…
listView.setSelection(listAdapter.getCount() - 1);
}
});
}
1、一個屬性
ListView有一個屬性叫做stackFromBottom,你可以在xml文件中定義該屬性,就像這樣子:
android:stackFromBottom="true|false"
- 1
- 2
ListView默認該屬性是false。該屬性的含義是列表是否從ListView的最底部開始展示,若爲true,則從最底部展示,否則從最頂部開始展示。看一下下面的效果就知道是什麼意思了。
假設我們定義了一個main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listview"
android:stackFromBottom="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</RelativeLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
其對應的MainActivity.java文件如下:
package com.example.willenhuang.helloworld;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView listView = (ListView) findViewById(R.id.listview);
listView.setStackFromBottom(false);
List<String> dataList = new ArrayList<String>();
for (int i = 0; i < 20; i++) {
dataList.add("test" + i);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, dataList);
listView.setAdapter(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
當我們將android:stackFromBottom設置爲true時,得到的效果如下圖:
我們可以看到列表的排列順序並沒有變化,但是卻是從底部開始向上展示。當然當我們去掉該屬性後,就可以見到正常的效果,如下圖所示,這和我們平常的ListView就是一樣的了。
2、如何滑動到頂部
使用下面的代碼可以將你的ListView滑動到頂部:
if (!YourListView.isStackFromBottom()) {
YourListView.setStackFromBottom(true);
}
YourListView.setStackFromBottom(false);
- 1
- 2
- 3
- 4
- 5
說明:從上面的分析和效果圖可以知道,stackFromBottom的屬性如果爲true,則表示列表從最下面開始顯示要展示的內容。如果爲false,則表示列表從最下面開始顯示要展示的內容。這裏要特別說明一下,如果你認爲最終都要執行YourListView.setStackFromBottom(false);這一語句,那麼YourListView.setStackFromBottom(true);就沒有啥意義了。其實並不是這樣的,當我們將YourListView.setStackFromBottom(true);該語句去掉的時候,會發現並沒有任何效果,列表並沒有滑動到頂部。所以我這裏猜測是不是這樣的原因:本來列表的屬性是setStackFromBottom(false),然後你繼續執行YourListView.setStackFromBottom(false);應該是沒有任何效果的。必須要將列表的屬性先改變,然後再改回來纔會達到滑動到頂部的效果。所以必須要執行YourListView.setStackFromBottom(true);這一語句。
3、如何滑動到底部
if (YourListView.isStackFromBottom()) {
YourListView.setStackFromBottom(false);
}
YourListView.setStackFromBottom(true);
- 1
- 2
- 3
- 4
- 5
道理和滑動到頂部是一樣的,這裏就不再講一遍了。
4、總結
相比於其他方式進行ListView的自動滑動到頂部(底部),使用setStackFromStack還是挺好用的。但是使用過程中有不理解的可以自己寫一個demo出來比對比對。這樣就更能加深對新知識的理解了。