最近在做分组列表,头部悬停的效果,在github上就搜到了StickyListHeaders(https://github.com/emilsjolander/StickyListHeaders)这个库,自己动手实现了一个demo,实际效果图见文末。
引用类库:
implementation 'se.emilsjolander:stickylistheaders:2.7.0'
子布局item_pay_bill_month_body_list.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/item_body_tv1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="内容" android:textSize="20sp" /> <TextView android:id="@+id/item_body_tv2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="内容" android:textSize="20sp" /> <TextView android:id="@+id/item_body_tv3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="内容" android:textSize="20sp" /> <TextView android:id="@+id/item_body_tv4" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="内容" android:textSize="20sp" /> <TextView android:id="@+id/item_body_tv5" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="内容" android:textSize="20sp" /> </LinearLayout>
头部布局item_pay_bill_month_header_list.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/item_head_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#f00" android:text="头部" android:textSize="30sp" /> </LinearLayout>
列表适配器PayBillMonthListAdapter.java:
package com.aldx.hccraftsman.adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.aldx.hccraftsman.R; import com.aldx.hccraftsman.model.PayBillMonth; import java.util.ArrayList; import java.util.List; import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; /** * author: chenzheng * created on: 2018/11/3 11:24 * description: */ public class PayBillMonthListAdapter extends BaseAdapter implements StickyListHeadersAdapter { private Context context; private List<PayBillMonth> monthList = new ArrayList<>(); public PayBillMonthListAdapter(Context context) { this.context = context; } public void setItems(List<PayBillMonth> monthList) { this.monthList = monthList; notifyDataSetChanged(); } //设置数据的个数 @Override public int getCount() { return monthList.size(); } //设置item的条数 @Override public Object getItem(int i) { return monthList.get(i); } //获得相应数据集合中特定位置的数据项 @Override public long getItemId(int i) { return i; } //获得头部相应数据集合中特定位置的数据项 @Override public long getHeaderId(int position) { return monthList.get(position).yearmonth; } //绑定内容的数据 @Override public View getView(int i, View view, ViewGroup viewGroup) { BodyHolder bodyHolder = null; if (view == null) { view = LayoutInflater.from(context).inflate(R.layout.item_pay_bill_month_body_list, viewGroup, false); bodyHolder = new BodyHolder(view); view.setTag(bodyHolder); } else { bodyHolder = (BodyHolder) view.getTag(); } //设置数据 bodyHolder.bodyTv.setText(monthList.get(i).name); return view; } //绑定头部的数据 @Override public View getHeaderView(int position, View convertView, ViewGroup parent) { HeadHolder headHolder = null; if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.item_pay_bill_month_header_list, parent, false); headHolder = new HeadHolder(convertView); convertView.setTag(headHolder); } else { headHolder = (HeadHolder) convertView.getTag(); } //设置数据 headHolder.headTv.setText(monthList.get(position).monthName); return convertView; } //头部的内部类 class HeadHolder { private TextView headTv; public HeadHolder(View itemHeadView) { headTv = (TextView) itemHeadView.findViewById(R.id.item_head_tv); } } //内容的内部类 class BodyHolder { private TextView bodyTv; public BodyHolder(View itemBodyView) { bodyTv = (TextView) itemBodyView.findViewById(R.id.item_body_tv1); } } }
PayBillMonthListActivity.java:
package com.aldx.hccraftsman.activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.aldx.hccraftsman.R; import com.aldx.hccraftsman.adapter.PayBillMonthListAdapter; import com.aldx.hccraftsman.model.PayBillMonth; import java.util.ArrayList; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; import se.emilsjolander.stickylistheaders.StickyListHeadersListView; /** * author: chenzheng * created on: 2018/11/3 14:36 * description: 月度账单 */ public class PayBillMonthListActivity extends BaseActivity { @BindView(R.id.back_iv) ImageView backIv; @BindView(R.id.layout_back) LinearLayout layoutBack; @BindView(R.id.title_tv) TextView titleTv; @BindView(R.id.right_tv) TextView rightTv; @BindView(R.id.layout_right) LinearLayout layoutRight; @BindView(R.id.stickyListView) StickyListHeadersListView stickyListView; private String companyId; private List<PayBillMonth> list = new ArrayList<>(); private PayBillMonthListAdapter payBillMonthListAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_pay_bill_month_list); companyId = getIntent().getStringExtra("companyId"); ButterKnife.bind(this); initView(); initData(); } private void initData() { for (int i = 0; i < 10; i++) { PayBillMonth p1 = new PayBillMonth(); p1.yearmonth = 201811; p1.monthName = "2018年11月"; p1.name = "詹大三" + i; list.add(p1); } for (int i = 0; i < 7; i++) { PayBillMonth p1 = new PayBillMonth(); p1.yearmonth = 201810; p1.monthName = "2018年10月"; p1.name = "刘丽丽" + i; list.add(p1); } for (int i = 0; i < 2; i++) { PayBillMonth p1 = new PayBillMonth(); p1.yearmonth = 201809; p1.monthName = "2018年09月"; p1.name = "姜大成" + i; list.add(p1); } payBillMonthListAdapter.setItems(list); } private void initView() { titleTv.setText("月度账单"); payBillMonthListAdapter = new PayBillMonthListAdapter(this); stickyListView.setAdapter(payBillMonthListAdapter); } @OnClick({R.id.layout_back, R.id.layout_right}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.layout_back: finish(); break; case R.id.layout_right: break; } } public static void startActivity(Context context, String companyId) { Intent intent = new Intent(context, PayBillMonthListActivity.class); intent.putExtra("companyId", companyId); context.startActivity(intent); } }
页面布局activity_pay_bill_month_list.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include android:id="@+id/include_id" layout="@layout/titlelayout_theme" android:layout_width="match_parent" android:layout_height="wrap_content" /> <se.emilsjolander.stickylistheaders.StickyListHeadersListView android:id="@+id/stickyListView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
实体类PayBillMonth:
package com.aldx.hccraftsman.model; /** * author: chenzheng * created on: 2018/11/3 14:18 * description: */ public class PayBillMonth { public long yearmonth; public String monthName; public String name; public String money; public String time; }
效果图: