【android】ListView 的 transcriptMode 选项
2016-03-10 21:04
393 查看
目录
操作环境导读
调用方式
布局文件设置
源码分析
实例
操作环境
操作系统: win7-64bit 旗舰版android 版本: android-23
模拟器:海马玩模拟器 0.9.0 Beta( android 4.2.2 )
导读
默认情况下,当添加的 Item 超出 ListView 的范围后,ListView 并没有刷新让最新一条显示出来。而在 qq/微信 聊天中,发新的消息后会自动滚动显示出最下面的一条信息。调用方式
AbsListView.java:public int getTranscriptMode() // 用于查询当前的 transcript 模式
void setTranscriptMode(int mode) // 用于设置 transcript 模式
AbsListView.TRANSCRIPT_MODE_DISABLED // 禁用 AbsListView.TRANSCRIPT_MODE_NORMAL // 正常状态 AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL // 总是滚动到最新一条
布局文件设置
<ListView android:id="@+id/lv_test" android:layout_width="match_parent" android:layout_height="300dp" <!-- 以下模式只能选一种 --> android:transcriptMode="normal" android:transcriptMode="disabled" android:transcriptMode="alwaysScroll" >
源码分析
获取当前模式:/** * Returns the current transcript mode. * * @return {@link #TRANSCRIPT_MODE_DISABLED}, {@link #TRANSCRIPT_MODE_NORMAL} or * {@link #TRANSCRIPT_MODE_ALWAYS_SCROLL} */ public int getTranscriptMode() { return mTranscriptMode; }
设置模式:
/** * 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; }
根据 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(); } ... 省略 ... }
@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; } }
实例
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>
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); } }); }
效果图:
disable 状态:
normal 状态:
always 状态:
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories