第六章 使用列表(list)和适配器(adapter)
来源:互联网 发布:最新淘宝打包员招聘 编辑:程序博客网 时间:2024/06/03 23:50
列表和适配器是安卓开发中需要重点掌握的两个概念,在这章中,我们将学习列表和适配器的一些技巧。
1.处理空列表
当列表中没有内容的时候,可以展示一张图片或者文字进行提示,只需要使用ListView的setEmpltyView(view)方法即可。当adapter为null或者adapter的 isEmpty()方法返回true的时候就会展示出来。
例如:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/my_list_view" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <ImageView android:id="@+id/empty_view" android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/empty_view" /></FrameLayout>当ListView为空时我们想展示ImageView这张图片,那么在java代码里可以这样写:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mListView = (ListView) findViewById(R.id.my_list_view); mListView.setEmptyView(findViewById(R.id.empty_view)); }
2.使用ViewHolder创建高效适配器
地球人都知道怎么用,这里就不重复了。
3.给ListView添加section headers
效果如图:
具体实现步骤如下:
首先,section header布局:把背景设置为蓝色,与listview的item区分开来
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/header" android:textSize="24sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#0000ff" />然后,页面布局:通过include把header添加进来,这样section header会保持在listview顶部
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white"> <ListView android:id="@+id/my_list" android:layout_width="match_parent" android:layout_height="match_parent" /> <include layout="@layout/header" /></FrameLayout>
再是listview的item布局:每一个item都包含一个header,需要时显示,不需要时隐藏
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <include layout="@layout/header" /> <TextView android:id="@+id/label" style="@android:style/TextAppearance.Large" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>adapter的getview方法中:当item在顶部,或者item的首字母与前一个item的首字母不一样时,就显示section header
public View getView(int position, View view, ViewGroup parent) { final ViewHolder viewHolder; if (view == null) { view = activity.getLayoutInflater().inflate(R.layout.list_item, parent, false); viewHolder=new ViewHolder(); viewHolder.header=(TextView) view.findViewById(R.id.header); viewHolder.label=(TextView)view.findViewById(R.id.label); view.setTag(viewHolder); }else { viewHolder=(ViewHolder)view.getTag(); } //赋值 String label = countries[position]; if (position == 0 || countries[position - 1].charAt(0) != label.charAt(0)) { viewHolder.header.setVisibility(View.VISIBLE); viewHolder.header.setText(label.substring(0, 1)); } else { viewHolder.header.setVisibility(View.GONE); } viewHolder.label.setText(countries[position]); return view; } static class ViewHolder{ TextView header; TextView label; }
然后在activity中:初始化ListView,并添加滑动监听,使得处于listview顶部的section header的标签与item的首字母相同。
public class MainActivity extends Activity { private TextView topHeader; private int topVisiblePosition = -1; private ListView mList; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list); topHeader = (TextView) findViewById(R.id.header); mList=(ListView)findViewById(R.id.my_list); mList.setAdapter(new SectionAdapter(this, Countries.COUNTRIES)); mList.setOnScrollListener( new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // Empty. } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (firstVisibleItem != topVisiblePosition) { topVisiblePosition = firstVisibleItem; setTopHeader(firstVisibleItem); } } }); setTopHeader(0); } private void setTopHeader(int pos) { final String text = Countries.COUNTRIES[pos].substring(0, 1); topHeader.setText(text); }}
4.使用委托delegate让Activity和Adapter通信
比如一个ListView中有一个按钮,点击按钮能删除当前item。如果Activity和Adapter写在两个不同的java文件中,那么在adapter中需要能修改ListView中的数据,就可以使用委托来实现。adapter代码如下:
public class NumbersAdapter extends ArrayAdapter<Integer> { public static interface NumbersAdapterDelegate { void removeItem(Integer value); } private LayoutInflater mInflator; private NumbersAdapterDelegate mDelegate; public NumbersAdapter(Context context, List<Integer> objects) { super(context, 0, objects); mInflator = LayoutInflater.from(context); } @Override public View getView(int position, View cv, ViewGroup parent) { if (null == cv) { cv = mInflator.inflate(R.layout.number_row, parent, false); } final Integer value = getItem(position); TextView tv = (TextView) cv.findViewById(R.id.numbers_row_text); tv.setText(value.toString()); View button = cv.findViewById(R.id.numbers_row_button); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (null != mDelegate) { mDelegate.removeItem(value); } } }); return cv; } public void setDelegate(NumbersAdapterDelegate delegate) { mDelegate = delegate; }}其实就是在adapter中定义了一个接口,然后在item的按钮点击事件中调用接口中的方法。
Activity代码如下:让activity继承adapter中的接口,然后实现接口中的方法。当用户点击item中的按钮,就会调用activity中的removeItem方法
public class MainActivity extends Activity implements NumbersAdapterDelegate { private ListView mListView; private ArrayList<Integer> mNumbers; private NumbersAdapter mAdapter; private EditText mEditText; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mEditText = (EditText) findViewById(R.id.main_edittext); mListView = (ListView) findViewById(R.id.main_listview); mNumbers = new ArrayList<Integer>(); mAdapter = new NumbersAdapter(this, mNumbers); mListView.setAdapter(mAdapter); } @Override protected void onResume() { super.onResume(); mAdapter.setDelegate(this); } @Override protected void onPause() { super.onPause(); mAdapter.setDelegate(null); } @Override public void removeItem(Integer value) { mNumbers.remove(value); Toast.makeText(this, "Removed object: " + value, Toast.LENGTH_SHORT).show(); mAdapter.notifyDataSetChanged(); }}
5.其它
1.设定屏幕的方向其中一个方法是在manifest.xml里设定activity的属性 android:screenOrientation="landscape"
也可在Activity的Java文件中通过代码设定:setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
setRequestedOrientation 参数说明:
- 系统默认:此为默认值,由Android系统自己选择适当的方向,选择策略视具体设备的配置情况而定,因此不同的设备会有不同的方向选择;
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED - 锁定直式:竖屏 (肖像照) , 显示时高度大于宽度 ;
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT - 锁定横式:横屏(风景照) ,显示时宽度大于高度;
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE - 随使用者当下:用户当前的首选方向;
ActivityInfo.SCREEN_ORIENTATION_USER - 与活动线程下相同的设定:继承Activity堆栈中当前Activity下面的那个Activity的方向;
ActivityInfo.SCREEN_ORIENTATION_BEHIND - 不随SENSOR改变:忽略物理感应器 即显示方向与物理感应器无关,不管用户如何旋转设备显示方向都不会随着改变("unspecified"设置除外);
ActivityInfo.SCREEN_ORIENTATION_NOSENSOR - 随SENSOR改变:由物理感应器决定显示方向,它取决于用户如何持有设备,当 设备 被旋转时方向会随之变化 在横屏与竖屏之间;
ActivityInfo.SCREEN_ORIENTATION_SENSOR
android:choiceMode="multipleChoice"choiceMode属性解析
none
0Normal list that does not indicate choices.singleChoice
1The list allows up to one choice.multipleChoice
2The list allows multiple choices.multipleChoiceModal
3The list allows multiple choices in a custom selection mode. 0 0
- 第六章 使用列表(list)和适配器(adapter)
- 列表和适配器(ListView和Adapter)
- 列表控件ListView和适配器Adapter
- android listview和适配器adapter的使用
- Adapter适配器的使用
- 适配器Adapter使用
- ListView和Adapter(适配器)
- Adapter适配器和ListView
- adapter适配器与LIST列表与listview的三者关系(自己看法)
- ListView和Adapter—数据适配器使用详情
- android_listView_适配器Adapter的使用
- Android适配器Adapter的使用
- Adapter适配器的基本使用
- ListView,GridView 和 适配器 Adapter
- 使用Adapter更新列表
- 适配器(adapter)模式--类适配器和对象适配器
- 13-4-1 Android中list和Adapter的使用
- 使用ListView显示信息列表,用监听器和适配器,操作
- mac系统编辑快捷键
- Windows下忘记MySQL root密码的解决方法
- 深度学习框架Keras的安装
- libnet在arm上的移植 ---fwqlzz love is for ever
- Xutils 的框架问题retry error, curr request is null Android开发之网络请问问题
- 第六章 使用列表(list)和适配器(adapter)
- Qt学习记录--05 函数指针以及类函数指针用于Qt信号槽
- build.gradle and gradle.property的关系和部分使用
- android studio利用图形界面打包生成apk
- 抓包工具基础了解
- 心灵鸡汤之20160419
- Web应用程序中的服务器错误 (<authentication mode="Forms">)
- linux驱动基础系列--Linux下Spi接口Wifi驱动分析
- android CursorLoader用法介绍