ViewStub经常用在ListView中,用来隐藏一些操作,使用起来也很简单,主要就是在ListView的Item中通过一个ViewStub来引用被隐藏的布局文件。监听用户点击Item,判断下当前是可见还是不可见,实时进行状态的转换即可。
效果图如下:
下面看代码:
MainActivity.java: 设置数据源
public class MainActivity extends Activity { private ListView lvList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvList = (ListView)findViewById(R.id.lv_list); List<Map<String, String>> data = new ArrayList<Map<String, String>>(); Map<String, String> map; for(int i = 0; i < 20; i++){ map = new HashMap<String, String>(); map.put("1234", "1234"); data.add(map); } MainAdapter mainAdapter = new MainAdapter(this, data); lvList.setAdapter(mainAdapter); } }
MainAdapter.java:
自定义Adapter,在getView中实现我们的效果:
public class MainAdapter extends BaseAdapter { // private Context context; private List<Map<String, String>> data; private LayoutInflater layoutInflater; public MainAdapter(Context context, List<Map<String, String>> data) { // this.context = context; this.data = data; layoutInflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } class ViewHolder { RelativeLayout rlListItem;// 点击展开或收起ViewStub View vsOperations;// 点击后显示的更多的操作 ImageButton ibCompelete;// 打钩按钮 ImageButton ibImportant;// 感叹号按钮 ImageButton ibNotify;// 提醒按钮 ImageButton ibLove;// 爱心按钮 ImageButton ibShare;// 分享按钮 } @Override public View getView(int position, View convertView, ViewGroup parent) { final ViewHolder viewHolder; if (convertView == null) { convertView = layoutInflater.inflate(R.layout.list_item_main_task, null); viewHolder = new ViewHolder(); viewHolder.rlListItem = (RelativeLayout) convertView .findViewById(R.id.rl_list_item); viewHolder.vsOperations = (ViewStub) convertView .findViewById(R.id.vs_detail_operations); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); viewHolder.vsOperations.setVisibility(View.GONE); } viewHolder.rlListItem.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if (viewHolder.vsOperations.getVisibility() == View.GONE) { if(viewHolder.vsOperations instanceof ViewStub){ //关键! viewHolder.vsOperations = ((ViewStub)viewHolder.vsOperations).inflate(); } viewHolder.vsOperations.setVisibility(View.VISIBLE); } else { viewHolder.vsOperations.setVisibility(View.GONE); } } }); Log.e("111", "getView"); return convertView; } @Override public int getCount() { // TODO Auto-generated method stub return data.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return data.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } }
activity_main.xml:主界面布局就一个ListView
<RelativeLayout 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" tools:context=".MainActivity" > <ListView android:id="@+id/lv_list" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
list_item_main_task.xml: ListView中的每个Item,注意里面的ViewStub,通过它来引用一个布局文件,即隐藏的操作按钮。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <!-- 每个ListItem除了ViewStub,都在这个标签里面 --> <RelativeLayout android:id="@+id/rl_list_item" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/bg_list_item_task" android:gravity="center" > <!-- android:descendantFocusability="blocksDescendants" 当ListView setOnItemClickListener点击没有效果的时候,加上这个 --> <!-- 任务的名称和超期时间 --> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:gravity="center_vertical" android:orientation="vertical" > <TextView android:id="@+id/tv_task_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="任务1" android:textColor="#404040" android:textSize="22dp" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" > <TextView android:id="@+id/tv_over_date" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="超期2天" android:textColor="#ff0000" android:textSize="15dp" /> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dip" android:text="张小三" android:textColor="#333333" android:textSize="15dp" /> </LinearLayout> </LinearLayout> </RelativeLayout> <ViewStub android:id="@+id/vs_detail_operations" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout="@layout/view_stub_tool_bar" /> </LinearLayout>
view_stub_tool_bar.xml: 被隐藏的操作按钮
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical" android:paddingTop="8dip" android:background="@drawable/bg_list_item_task_view_stub" > <ImageButton android:id="@+id/btn_compelete" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:minHeight="55dp" android:background="@null" android:src="@drawable/ico_complete_selector" /> <ImageButton android:id="@+id/btn_important" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:minHeight="55dp" android:background="@null" android:src="@drawable/ico_important_selector" /> <ImageButton android:id="@+id/btn_" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:minHeight="55dp" android:background="@null" android:src="@drawable/ico_notify_selector" /> <ImageButton android:id="@+id/btn_" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:minHeight="55dp" android:background="@null" android:src="@drawable/ico_love_selector" /> <ImageButton android:id="@+id/btn_" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:minHeight="55dp" android:background="@null" android:src="@drawable/ico_share_selector" /> </LinearLayout>
一些资源文件这里就不贴出来了,有兴趣的同学可以下载demo来看看。
使用ViewStub的好处是,它并没有实例化这个View对象,而是在用户点击的时候才进行实例化,这样可以提高效率。特别是当你的listItem比较复杂的时候,效果很明显。
项目地址:https://github.com/michaelye/ViewStubDemo.git