【android】ListView 的 transcriptMode 选项
2017-01-13 16:47
483 查看
默认情况下,当添加的 Item 超出 ListView 的范围后,ListView 并没有刷新让最新一条显示出来。而在 qq/微信 聊天中,发新的消息后会自动滚动显示出最下面的一条信息。
1
1
2
3
1
2
3
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
设置模式:
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
根据 mTranscriptMode 的值来对应设置 mLayoutMode 的状态:
如果是 TRANSCRIPT_MODE_ALWAYS_SCROLL:则 强制 从 ListView 的底部开始刷新;
如果是 TRANSCRIPT_MODE_NORMAL:如果当前的最后一个 Item 在 ListView 显示范围内,adapter 数据集内容变化时就从滚动底部;否则不滚动到底部!
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
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
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
MainActivity.java:
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
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
效果图:
disable 状态:
normal 状态:
always 状态:
顶0
踩
调用方式
AbsListView.java:public int getTranscriptMode() // 用于查询当前的 transcript 模式1
1
void setTranscriptMode(int mode) // 用于设置 transcript 模式1
1
AbsListView.TRANSCRIPT_MODE_DISABLED // 禁用 AbsListView.TRANSCRIPT_MODE_NORMAL // 正常状态 AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL // 总是滚动到最新一条1
2
3
1
2
3
布局文件设置
<ListView android:id="@+id/lv_test" android:layout_width="match_parent" android:layout_height="300dp" <!-- 以下模式只能选一种 --> android:transcriptMode="normal" android:transcriptMode="disabled" android:transcriptMode="alwaysScroll" >1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
源码分析
获取当前模式:/** * Returns the current transcript mode. * * @return {@link #TRANSCRIPT_MODE_DISABLED}, {@link #TRANSCRIPT_MODE_NORMAL} or * {@link #TRANSCRIPT_MODE_ALWAYS_SCROLL} */ public 4000 int getTranscriptMode() { return mTranscriptMode; }1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
设置模式:
/** * Puts the list or grid into transcript mode. In this mode the list or grid will always scroll * to the bottom to show new items. * * @param mode the transcript mode to set * * @see #TRANSCRIPT_MODE_DISABLED * @see #TRANSCRIPT_MODE_NORMAL * @see #TRANSCRIPT_MODE_ALWAYS_SCROLL */ public void setTranscriptMode(int mode) { mTranscriptMode = mode; }1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
根据 mTranscriptMode 的值来对应设置 mLayoutMode 的状态:
如果是 TRANSCRIPT_MODE_ALWAYS_SCROLL:则 强制 从 ListView 的底部开始刷新;
如果是 TRANSCRIPT_MODE_NORMAL:如果当前的最后一个 Item 在 ListView 显示范围内,adapter 数据集内容变化时就从滚动底部;否则不滚动到底部!
@Override protected void handleDataChanged() { ... 省略 ... if (mTranscriptMode == TRANSCRIPT_MODE_ALWAYS_SCROLL) { mLayoutMode = LAYOUT_FORCE_BOTTOM; return; } else if (mTranscriptMode == TRANSCRIPT_MODE_NORMAL) { if (mForceTranscriptScroll) { mForceTranscriptScroll = false; mLayoutMode = LAYOUT_FORCE_BOTTOM; return; } final int childCount = getChildCount(); final int listBottom = getHeight() - getPaddingBottom(); final View lastChild = getChildAt(childCount - 1); final int lastBottom = lastChild != null ? lastChild.getBottom() : listBottom; if (mFirstPosition + childCount >= lastHandledItemCount && lastBottom <= listBottom) { mLayoutMode = LAYOUT_FORCE_BOTTOM; return; } // Something new came in and we didn't scroll; give the user a clue that // there's something new. awakenScrollBars(); } ... 省略 ... }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
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
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mSelector == null) { useDefaultSelector(); } final Rect listPadding = mListPadding; listPadding.left = mSelectionLeftPadding + mPaddingLeft; listPadding.top = mSelectionTopPadding + mPaddingTop; listPadding.right = mSelectionRightPadding + mPaddingRight; listPadding.bottom = mSelectionBottomPadding + mPaddingBottom; // Check if our previous measured size was at a point where we should scroll later. if (mTranscriptMode == TRANSCRIPT_MODE_NORMAL) { final int childCount = getChildCount(); final int listBottom = getHeight() - getPaddingBottom(); final View lastChild = getChildAt(childCount - 1); final int lastBottom = lastChild != null ? lastChild.getBottom() : listBottom; mForceTranscriptScroll = mFirstPosition + childCount >= mLastHandledItemCount && lastBottom <= listBottom; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
实例
test_list_view.xml:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/lv_test" android:layout_width="match_parent" android:layout_height="300dp" > </ListView> <Button android:id="@+id/btn_add_item" android:layout_width="match_parent" android:layout_height="40dp" android:text="增加新 item" /> <Button android:id="@+id/btn_set_disable" android:layout_width="match_parent" android:layout_height="40dp" android:text="不滚动" /> <Button android:id="@+id/btn_set_normal" android:layout_width="match_parent" android:layout_height="40dp" android:text="如果最后Item在显示范围内就滚动" /> <Button android:id="@+id/btn_set_always" android:layout_width="match_parent" android:layout_height="40dp" 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
23
24
25
26
27
28
29
30
31
32
33
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
MainActivity.java:
public class MainActivity extends Activity { ArrayList<String> mItemStrArr = new ArrayList<>(); ArrayAdapter mAdapter; int i = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test_list_view); this.testListViewTranscriptMode(); } void testListViewTranscriptMode(){ Button btnAddItem = (Button) this.findViewById(R.id.btn_add_item); Button btnSetDisable = (Button) this.findViewById(R.id.btn_set_disable); Button btnSetNormal = (Button) this.findViewById(R.id.btn_set_normal); Button btnSetAlways = (Button) this.findViewById(R.id.btn_set_always); ListView lv = (ListView)this.findViewById(R.id.lv_test); // 实例化对象 mAdapter = new ArrayAdapter(this, R.layout.test_item, R.id.tv_content, mItemStrArr); // 设置适配器 lv.setAdapter(mAdapter); btnAddItem.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mItemStrArr.add("item_" + i++); mAdapter.notifyDataSetChanged(); } }); // 设置监听 btnSetDisable.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ListView lv = (ListView)MainActivity.this.findViewById(R.id.lv_test); lv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_DISABLED); } }); btnSetNormal.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ListView lv = (ListView)MainActivity.this.findViewById(R.id.lv_test); lv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_NORMAL); } }); btnSetAlways.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ListView lv = (ListView)MainActivity.this.findViewById(R.id.lv_test); lv.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); } }); }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
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
效果图:
disable 状态:
normal 状态:
always 状态:
顶0
踩
相关文章推荐
- 【android】ListView 的 transcriptMode 选项
- 【android】ListView 的 transcriptMode 选项
- 【android】ListView 的 transcriptMode 选项
- 【慢慢学Android】:10.处理listview长按事件,删除所选项
- Android,ListView选项问题——getView刷新问题及单选框的实现
- Android开发:在ListView实现多选项CheckBox的例子
- Android笔记—自定义Listview控件的行选项背景与效果
- 【android】ListView 的 stackFromBottom 选项
- Listview 选项按下去黑了所有按钮的解决方法 ——android:cacheColorHint=“#00000000”
- Android ListView选项(View)清除背景色
- Android中为ListView的Item选项设置出场动画
- Android里针对ListView中选项进行排序的方法
- Android开发,listview+radiobutton实现单选(选项可编辑)
- android的listview点击获取当前选项值的方法
- android ListView 获取点击的选项
- Android ListView获得选项中的值
- Android基础教程(十)之-------ListView的应用
- Android基础教程(七)之----单选项框RadioGroup的综合应用
- Android中ListView的使用(不用ListActivity)
- Android入门第七篇之ListView (二)