先看下界面效果![最终实现效果](https://img-blog.csdn.net/20161021174033058),其实网上也有不少这类的代码。但基本上都或多或少有一些异常或不完善的地方。实现的思路就是listview中嵌套一个listview,然后第一个listview的item是覆写了LinearLayout的一个自定义布局,目的就是为了实现区分开第一条的效果。实现的代码很简单。
外层listview的adapter
public class CardAdapter extends BaseAdapter {
private Context mContext;
private List<List<CardItem>> mCardsList = new ArrayList<>();
private Card mCard;
public CardAdapter(Context mContext) {
this.mContext = mContext;
}
public void setDatas(List<List<CardItem>> cards) {
mCardsList.clear();
this.mCardsList = cards;
notifyDataSetChanged();
}
@Override
public int getCount() {
if (mCardsList != null)
return mCardsList.size();
return 0;
}
/**
* 返回的是个List对象,每个item是内部listview的填充内容
*/
@Override
public List<CardItem> getItem(int i) {
if (mCardsList != null)
return mCardsList.get(i);
return null;
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
mCard = new Card(mContext);
List<CardItem> mapCard = getItem(position);
mCard.setData(mapCard);
return mCard;
}
}
这个是自定义的LinearLayout布局:
public class Card extends LinearLayout {
private Context mContext;
private LayoutInflater mLayoutInflater;
private LinearLayout mLinearLayout;
private RelativeLayout mTitilelayout;
private TextView mDateView, mTitleView;
private ImageView mIconView;
private BobyListView mBobylist;
private BobyAdapter mBobyAdapter;
public Card(Context context) {
this(context, null);
}
public Card(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public Card(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
this.mContext = context;
if (mLayoutInflater == null) {
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
mLinearLayout = (LinearLayout) mLayoutInflater.inflate(R.layout.card_item, null);
mTitilelayout = (RelativeLayout) mLinearLayout.findViewById(R.id.titile_layout);
mDateView = (TextView) mLinearLayout.findViewById(R.id.tv_date);
mIconView = (ImageView) mLinearLayout.findViewById(R.id.title_icon);
mTitleView = (TextView) mLinearLayout.findViewById(R.id.title_title);
mBobylist = (BobyListView) mLinearLayout.findViewById(R.id.boby_list);
mTitilelayout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
mBobyAdapter = new BobyAdapter(mContext);
mBobylist.setAdapter(mBobyAdapter);
mBobylist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
}
});
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
addView(mLinearLayout, params);
}
public void setData(List<CardItem> list) {
if (list.size() == 0) {
return;
}
//如果只有一条,则只显示title内容,没有底部的listview。并将背景设为四个圆角
if (list.size() == 1) {
mTitilelayout.setBackground(mContext.getDrawable(R.drawable.round_title_bg));
} else {//否则只有右上和左上两个为圆角特效
mTitilelayout.setBackground(mContext.getDrawable(R.drawable.title_bg));
}
CardItem baseCard = list.get(0);//第一条是做为title显示的
mTitleView.setText(baseCard.getTitle());
Glide.with(mContext.getApplicationContext()).load(baseCard.getIcon_add()).placeholder(mContext.getDrawable(R.mipmap.no_picture)).centerCrop().into(mIconView);
mBobyAdapter.setData(list);
postInvalidate();
}
}
这是它的对应布局文件
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="15dp"
android:background="@drawable/card_bg"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/titile_layout"
android:layout_width="match_parent"
android:padding="4dp"
android:layout_height="135dp">
<ImageView
android:id="@+id/title_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@null" />
<TextView
android:id="@+id/title_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:padding="4dp"
android:background="@drawable/card_title_bg_black"
android:gravity="center_horizontal"
android:textColor="#FFFFFF"
android:textSize="16sp" />
</RelativeLayout>
<widget.BobyListView
android:id="@+id/boby_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:listSelector="@android:color/transparent"
android:divider="@color/color_bg_stoken"
android:dividerHeight="1px"
android:fadingEdge="none" />
</LinearLayout>
自定义的listview,为了适配高度的变化
public class BobyListView extends ListView {
public BobyListView(Context context) {
this(context, null);
}
public BobyListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BobyListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
内层listview的adapter
public class BobyAdapter extends BaseAdapter {
private List mList = new ArrayList<>();
private Context mContext;
private LayoutInflater mInflater = null;
public BobyAdapter(Context context) {
this.mContext = context;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void setData(List<CardItem> cards) {
mList.clear();
this.mList = cards;
notifyDataSetChanged();
}
/**
*因为第一个item是大图显示的title内容,所以到这里的时候list中的item数要减一
**/
@Override
public int getCount() {
if (mList != null) return mList.size() -1;
return 0;
}
@Override
public CardItem getItem(int i) {
if (mList != null) return mList.get(i);
return null;
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int position, View contentView, ViewGroup viewGroup) {
ViewHolder holder = null;
if (contentView == null) {
holder = new ViewHolder();
contentView = mInflater.inflate(R.layout.card_item_list, null);
holder.mTitle = (TextView) contentView.findViewById(R.id.title);
holder.mIcon = (ImageView) contentView.findViewById(R.id.icon);
contentView.setTag(holder);
} else {
holder = (ViewHolder) contentView.getTag();
}
**//注意是加1,因为第一条是title,这里是关键**
final CardItem baseCard = mList.get(position + 1);
//holder.mIcon.setTag(baseCard.getIcon_add());
Glide.with(mContext)
.load(baseCard.getIcon_add())
.centerCrop()
.placeholder(mContext.getDrawable(R.mipmap.no_picture))
//.transform(new GlideRoundTransform(mContext))
.into(holder.mIcon);
holder.mTitle.setText(baseCard.getTitle());
holder.address = baseCard.getNews_add();
holder.baseCard = baseCard;
//如果是最后一条内容
if(position == mList.size() -2){
contentView.setBackground(mContext.getDrawable(R.drawable.round_listview_listitem_selector));
}else{
contentView.setBackground(mContext.getDrawable(R.drawable.listview_listitem_selector));
}
return contentView;
}
static class ViewHolder {
public ImageView mIcon;
public TextView mTitle;
public String address;
public CardItem baseCard;
}
}
这里写链接内容