分组列表在iOS、以及android实际项目中均比较常见 本文是使用强大的RecyclerView来实现分组列表。先看代码:
1 首先activity_main.xml和android 5.0新特性 RecyclerView 使用初级主布局一样 不再赘述。
2.MainActivity.java
public class MainActivity extends ActionBarActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private List<String> mData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// setlayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//setAdapter
mData = new ArrayList<>();
for (int i = 0; i < 100; i++) {
mData.add("this is content:" + i);
}
mData.add(3,"this is title: 1");
mData.add(15,"this is title: 2");
mData.add(20,"this is title: 3");
mData.add(60,"this is title: 4");
mData.add(77,"this is title: 5");
mAdapter = new RecyclerViewAdapter(this,mData);
mRecyclerView.setAdapter(mAdapter);
}
}
上述中。只在数据mData中添加了 this is title作为标识。实际项目中需要添加相应的处理。
来看看我们的分组布局。
分为两个:
只有标题的分组头item_text.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="wrap_content"
android:clickable="true"
android:focusable="true"
android:background="?selectableItemBackground">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/text"
android:textSize="18sp"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:textColor="#0000ff"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</RelativeLayout>
以及具体的内容 item_image.xml(仍以上次的xml为例):
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item"
android:layout_width="match_parent"
android:layout_height="?listPreferredItemHeight"
android:clickable="true"
android:focusable="true"
android:foreground="?selectableItemBackground">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="@+id/image"
android:layout_width="?listPreferredItemHeight"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|right"
android:scaleType="center"
/>
</FrameLayout>
接下来是我们的adapter中真正的实现RecyclerViewAdapter.java:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_IMAGE = 0;
private static final int TYPE_GROUP = 1;
private List<String> mData = new ArrayList<>();
private Context mContext;
private boolean isTitle(int pos){
if(mData.get(pos).startsWith("this is title:")) {
return true;
}
return false;
}
public RecyclerViewAdapter(Context mContext, List<String> mData) {
this.mContext = mContext;
this.mData = mData;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater mInflater = LayoutInflater.from (mContext);
switch ( viewType ) {
case TYPE_IMAGE:
ViewGroup vImage = ( ViewGroup ) mInflater.inflate ( R.layout.item_image, parent, false );
ImageViewHolder vhImage = new ImageViewHolder ( vImage );
return vhImage;
case TYPE_GROUP:
ViewGroup vGroup = ( ViewGroup ) mInflater.inflate ( R.layout.item_text, parent, false );
GroupViewHolder vhGroup = new GroupViewHolder ( vGroup );
return vhGroup;
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch ( holder.getItemViewType () ) {
case TYPE_IMAGE:
ImageViewHolder imageViewHolder = ( ImageViewHolder ) holder;
imageViewHolder.mImage.setImageResource ( R.drawable.ic_reorder_grey_500_24dp);
imageViewHolder.mTitle.setText(mData.get(position));
break;
case TYPE_GROUP:
GroupViewHolder groupViewHolder = ( GroupViewHolder ) holder;
groupViewHolder.mTitle.setText ( mData.get(position));
break;
}
}
@Override
public int getItemCount() {
return mData.size ();
}
@Override
public int getItemViewType ( int position ) {
int viewType;
if (!isTitle(position) ) {
viewType = TYPE_IMAGE;
} else {
viewType = TYPE_GROUP;
}
return viewType;
}
public class GroupViewHolder extends RecyclerView.ViewHolder {
TextView mTitle;
public GroupViewHolder ( View itemView ) {
super(itemView);
mTitle= (TextView) itemView.findViewById(R.id.text);
}
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
TextView mTitle;
ImageView mImage;
public ImageViewHolder ( View itemView ) {
super(itemView );
mTitle= (TextView) itemView.findViewById(R.id.text);
mImage= (ImageView) itemView.findViewById(R.id.image);
}
}
}
该段代码。实际上上述代码跟listView的分组几乎一模一样。下面做一个简述:
//区分分组
1. private boolean isTitle(int pos)
2. 通过viewType创建对应的ViewHolder
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater mInflater = LayoutInflater.from (mContext);
switch ( viewType ) {
case TYPE_IMAGE:
ViewGroup vImage = ( ViewGroup ) mInflater.inflate ( R.layout.item_image, parent, false );
ImageViewHolder vhImage = new ImageViewHolder ( vImage );
return vhImage;
case TYPE_GROUP:
ViewGroup vGroup = ( ViewGroup ) mInflater.inflate ( R.layout.item_text, parent, false );
GroupViewHolder vhGroup = new GroupViewHolder ( vGroup );
return vhGroup;
}
return null;
}
3. 根据holder.getItemViewType ()获取对应的ViewHolder绑定对应的数据
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch ( holder.getItemViewType () ) {
case TYPE_IMAGE:
ImageViewHolder imageViewHolder = ( ImageViewHolder ) holder;
imageViewHolder.mImage.setImageResource ( R.drawable.ic_reorder_grey_500_24dp);
imageViewHolder.mTitle.setText(mData.get(position));
break;
case TYPE_GROUP:
GroupViewHolder groupViewHolder = ( GroupViewHolder ) holder;
groupViewHolder.mTitle.setText ( mData.get(position));
break;
}
}
4.重写 getItemViewType
@Override
public int getItemViewType ( int position ) {
int viewType;
if (!isTitle(position) ) {
viewType = TYPE_IMAGE;
} else {
viewType = TYPE_GROUP;
}
return viewType;
}