高仿微信公众号、QQ新闻CardList布局

先看下界面效果![最终实现效果](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;
}

}
这里写链接内容

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值