今天有些闲时间,就来分享一个最近手头的项目中实现二级列表的一个实现方法,写的不好,有啥看不明白的可以找我详聊。
这个二级列表是用ListView和GridView实现的,主要效果是打开时一级列表的第一个item默认被选中。并且随着点击,改变字体颜色和背景颜色
效果如图:
1. 实现的大概原理:
在一级列表的adapter(FraSearchSingleProductListAdapter.java)中设置一个成员属性:
private int selected=0
提供一个操作此属性的方法:
public void setSelected(int position){
this.selected=position;
}
根据selected的值来控制item显示的效果:
/**
* 根据selected(被点击的item)的值动态的决定控件的属性
* @param position
* @param view
*/
@Override
public void disposalView(int position, View view) { //此方法是在基类AbsBaseAdapter定义的一个方法,复写可以控制item的view
if (position==selected) {
view.setBackgroundResource(R.drawable.bg_search_catagory_list_item_bg);
ViewHolder viewHolder = (ViewHolder) view.getTag();
TextView textView = (TextView) viewHolder.getView(R.id.txt_fra_search_single_product_category_list_item);
textView.setTextColor(0xffec5252);
}else {
view.setBackgroundResource(R.color.app_bg_gray_f0);
ViewHolder viewHolder = (ViewHolder) view.getTag();
TextView textView = (TextView) viewHolder.getView(R.id.txt_fra_search_single_product_category_list_item);
textView.setTextColor(0xff999999);
}
}
在LIstView的点击事件中调用:
categoryList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//改变被点击的item的背景,字体颜色
categorylistAdapter.setSelected(i);
categorylistAdapter.notifyDataSetChanged();
//加载显示子类数据
loadSubclassDatas(i);
}
});
2.文件列表:
适配器:
BaseAdapter.java
AbsBaseAdapter.java
FraSearchSingleProductListAdapter.java
FraSearchSingleProductSubListAdapter.java
Fragment:
FragmentSearchSingleProduct.java
3.全部代码内容:
BaseAdapter.java
public abstract class BaseAdapter<T> extends android.widget.BaseAdapter {
protected List<T> mList;
protected Context context;
private String TAG="BaseAdapter";
public BaseAdapter(Context context) {
this.context = context;
mList=new ArrayList<>();
}
/**
* 设置数据
* @param list
*/
public void setDatas(List<T> list){
this.mList=list;
this.notifyDataSetChanged();
}
/**
* 添加数据
* @param list
*/
public void addDatas(List<T> list){
this.mList.addAll(list);
this.notifyDataSetChanged();
}
/**
* 清理数据
*/
public void clearDatas(){
this.mList.clear();
this.notifyDataSetChanged();
}
@Override
public int getCount() {
return mList.size();
}
@Override
public T getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
}
AbsBaseAdapter.java
public abstract class AbsBaseAdapter<T> extends BaseAdapter{
public static final String TAG="AbsBaseAdapter";
private Context context;
private int resid;//无法确定item布局文件,所以通过外界传进来
public AbsBaseAdapter(Context context,int resid) {
super(context);
this.context=context;
this.resid=resid;
}
@Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
ViewHolder viewHolder;
if(convertView != null){
viewHolder = (ViewHolder) convertView.getTag();
} else {
convertView = LayoutInflater.from(context).inflate(resid, null);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
}
//从viewholder中获取控件赋值
bindDatas(viewHolder, (T) mList.get(position));
disposalView(position,convertView);
return convertView;
}
/**
* 提供一个抽象方法,用于子适配器来进行数据绑定
*
* @param viewHolder
* @param data
*/
public abstract void bindDatas(ViewHolder viewHolder, T data);
/**
* 提供一个方法,外界可以重写用于对view控制处理
* @param position
*/
public void disposalView(int position ,View view){
}
/**
* ViewHolder的作用,缓存item布局中的控件对象,以免下一次再fingViewById
*/
class ViewHolder {
//使用一个Map集合,用来存放需要使用到的控件对象,key值即为控件ID
private Map<Integer, View> mapCache = new HashMap<>();
//item的布局对象
private View layoutView;
public ViewHolder(View layoutView) {
this.layoutView = layoutView;
}
//提供一个获得布局中子控件的方法,参数为控件id
public View getView(int id) {
if (mapCache.containsKey(id)) {//查看该控件是否存在于map集合中
return mapCache.get(id);//如果存在直接从map中获得该控件,并返回
} else {
View view = layoutView.findViewById(id);//如果不存在,那么需要从布局对象中,findViewById
mapCache.put(id, view);//缓存进map集合中
return view;
}
}
}
}
FraSearchSingleProductListAdapter.java
/**
*
* 搜索界面 单品 一级列表
*/
public class FraSearchSingleProductListAdapter extends AbsBaseAdapter<SearchCategoryListEntity.DataEntity>{
private int selected=0;
private static final String TAG = "FraSearchSingleProductListAdapter";
private Context context;
public FraSearchSingleProductListAdapter(Context context) {
super(context, R.layout.fragment_search_single_product_category_list_item);
}
@Override
public void bindDatas(ViewHolder viewHolder, SearchCategoryListEntity.DataEntity data) {
((TextView)viewHolder.getView(R.id.txt_fra_search_single_product_category_list_item)).setText(data.getName());
}
/**
* 根据selected(被点击的item)的值动态的决定控件的属性
* @param position
* @param view
*/
@Override
public void disposalView(int position, View view) {
if (position==selected) {
view.setBackgroundResource(R.drawable.bg_search_catagory_list_item_bg);
ViewHolder viewHolder = (ViewHolder) view.getTag();
TextView textView = (TextView) viewHolder.getView(R.id.txt_fra_search_single_product_category_list_item);
textView.setTextColor(0xffec5252);
}else {
view.setBackgroundResource(R.color.app_bg_gray_f0);
ViewHolder viewHolder = (ViewHolder) view.getTag();
TextView textView = (TextView) viewHolder.getView(R.id.txt_fra_search_single_product_category_list_item);
textView.setTextColor(0xff999999);
}
}
public void setSelected(int position){
this.selected=position;
}
}
FraSearchSingleProductSubListAdapter.java
/**
*
* 搜索界面 单品 二级列表
*/
public class FraSearchSingleProductSubListAdapter extends AbsBaseAdapter<SearchCategoryListEntity.DataEntity.SubclassEntity>{
public FraSearchSingleProductSubListAdapter(Context context) {
super(context, R.layout.fragment_search_single_product_category_sub_item);
}
@Override
public void bindDatas(ViewHolder viewHolder, SearchCategoryListEntity.DataEntity.SubclassEntity data) {
ImageView imageView = (ImageView) viewHolder.getView(R.id.img_fra_search_single_product_category_sub_item_ico);
BanTangAPP.getApp().getImageLoader().displayImage(data.getIcon(),imageView);
((TextView)viewHolder.getView(R.id.txt_fra_search_single_product_category_sub_item_title)).setText(data.getName());
}
}
FragmentSearchSingleProduct.java
/**
* Created by zzh on 2016/1/15.
* 搜索界面 单品
*
*/
public class FragmentSearchSingleProduct extends BaseFragment{
public static final String TAG="FragmentSearchSingleProduct";
//一级类目列表
@ViewInject(R.id.list_fra_search_single_product_category)
private ListView categoryList;
//二级类目
@ViewInject(R.id.grid_fra_search_single_product_content)
private GridView productGrid;
@ResInject(id = R.string.network_error,type = ResType.String)
private String networkErro;
//单品数据接口
private String categoryUrl;
//分类数据
private List<SearchCategoryListEntity.DataEntity> dataEntities;
//一级类目
private FraSearchSingleProductListAdapter categorylistAdapter;
//二级类目
private FraSearchSingleProductSubListAdapter subListAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
categoryUrl=URL.CATEGORY_LIST_URL;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_search_single_product,container, false);
}
@Override
protected void initView(View view) {
//一级目录
categorylistAdapter = new FraSearchSingleProductListAdapter(getActivity());
categoryList.setAdapter(categorylistAdapter);
//二级目录
subListAdapter=new FraSearchSingleProductSubListAdapter(getActivity());
productGrid.setAdapter(subListAdapter);
categoryList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//改变被点击的item的背景,字体颜色
categorylistAdapter.setSelected(i);
categorylistAdapter.notifyDataSetChanged();
//加载显示子类数据
loadSubclassDatas(i);
}
});
}
private void loadSubclassDatas(int i) {
subListAdapter.setDatas(dataEntities.get(i).getSubclass());
}
@Override
protected void loadDatas() {
NetUtils.RequestParamsBuilder builder=new NetUtils.RequestParamsBuilder();
RequestParams params = builder.addPostParameter(BanTang.CLIENT_ID_KEY, BanTang.CLIENT_ID_VALUE)
.addPostParameter(BanTang.CLIENT_SECRET_KEY, BanTang.CLIENT_SECRET_VALUE)
.addPostParameter("is_new", "1").build();
NetUtils.doPost(categoryUrl, params, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
L.d(TAG,responseInfo.result);
try {
SearchCategoryListEntity searchCategoryListEntity = JsonUtils.perse(responseInfo.result, SearchCategoryListEntity.class);
dataEntities = searchCategoryListEntity.getData();
if (dataEntities.size()>0) {
categorylistAdapter.setDatas(dataEntities);
subListAdapter.setDatas(dataEntities.get(0).getSubclass());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(HttpException error, String msg) {
Toast.makeText(getActivity(), networkErro, Toast.LENGTH_SHORT).show();
}
});
}
}