此贴没有大量水帖文字,读者请放心,代码简单明了,阅读可懂,轻松入门,高手勿喷!
效果如下:
废话不多说,直接附代码:
分包如下:
View层
ISortView接口层
public interface ISortView { // 展示左侧数据 void ShowLeftData(LeftBean leftBean); // 展示右侧数据 void ShowRightData(RightBean rightBean); }
MyGridView(这个类用于修改GridView的高度,可随内容长度而增高)
public class MyGridView extends GridView { public MyGridView(Context paramContext, AttributeSet paramAttributeSet) { super(paramContext, paramAttributeSet); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //makeMeasureSpec根据提供的大小值和模式创建一个测量值(格式) int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
SortFragment
public class SortFragment extends Fragment implements ISortView { SortPresenter presenter; LeftAdapter leftAdapter; @BindView(R.id.sort_left_listview) ListView sortLeftListview; Unbinder unbinder; @BindView(R.id.sort_right_listview) ListView sortRightListview; RightAdapter right_adapter; private boolean isLogin; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.sort, null); init(); unbinder = ButterKnife.bind(this, view); return view; } private void init() { presenter = new SortPresenter(this); /*初始化 默认展示左侧数据*/ presenter.GetData(); } @Override public void onResume() { super.onResume(); presenter = new SortPresenter(this); /*初始化 默认展示左侧数据*/ presenter.GetData(); } @Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind(); } @Override public void ShowLeftData(LeftBean leftBean) { /*配置左侧适配器你*/ leftAdapter = new LeftAdapter(leftBean, getActivity()); sortLeftListview.setAdapter(leftAdapter); /*左侧的监听事件*/ leftClick(); } @Override public void ShowRightData(RightBean rightBean) { /*展示右侧数据*/ right_adapter = new RightAdapter(rightBean, getActivity()); sortRightListview.setAdapter(right_adapter); /*右侧条目的点击事件*/ right_adapter.GetItemData(new RightAdapter.GetItemData() { @Override public void getItemData(String name, String pscid) { ToastUtil.show(getActivity(), "--" + name + "." + pscid, 2000); } }); } private void leftClick() { leftAdapter.setClickName(new LeftAdapter.ClickName() { @Override public void Clickname(int cid) { /*请求右侧数据*/ presenter.GetRightData(cid); } }); } }
Model层
public interface ISortModel { // 请求数据的接口 void GetData(); // 请求右侧数据的接口 void GetRightData(int cid); }
public class SortModel implements ISortModel { // 定义接口 用于保存数据 LeftBean bean; // 保存右侧数据 RightBean rightBean; public interface OnLeftFinish { void onFinish(LeftBean bean); } private OnLeftFinish onLeftfinish; public SortModel(OnLeftFinish onLeftfinish, OnRightFinish onrightfinish) { this.onLeftfinish = onLeftfinish; this.onrightfinish = onrightfinish; } public interface OnRightFinish { void onRightFinish(RightBean bean); } private OnRightFinish onrightfinish; @Override public void GetData() { Observable<LeftBean> leftData = SortLeftRetroFactory.getInstance().getLeftData(Field.SORT_LEFT_PATH); leftData.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<LeftBean>() { @Override public void onCompleted() { Log.d("sort", "onCompleted: "); } @Override public void onError(Throwable e) { Log.d("sort", "onError: "); e.printStackTrace(); } @Override public void onNext(LeftBean leftBean) { Log.d("sort", "onNext: " + leftBean.getMsg()); bean = leftBean; onLeftfinish.onFinish(bean); } }); } @Override public void GetRightData(int cid) { HashMap<String,String> map = new HashMap<>(); map.put("cid",cid+""); final Observable<RightBean> rightData = RightRetroFactory.getInstance().getRightData(Field.SORT_RIGHT_PATH, map); rightData.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<RightBean>() { @Override public void onCompleted() { Log.d("sort", "onCompleted: "); } @Override public void onError(Throwable e) { Log.d("sort", "onError: "); e.printStackTrace(); } @Override public void onNext(RightBean bean) { Log.d("sort", "onNextRight: "+bean.getData().get(0).getName()+"--"); rightBean = bean; onrightfinish.onRightFinish(rightBean); } }); } }
Presenter层
public class SortPresenter implements SortModel.OnLeftFinish, SortModel.OnRightFinish { private final ISortView iSortView; private final SortModel sortModel; public SortPresenter(ISortView iSortView) { this.iSortView = iSortView; sortModel = new SortModel(this,this); } @Override public void onFinish(LeftBean bean) { iSortView.ShowLeftData(bean); } public void GetData(){ sortModel.GetData(); } public void GetRightData(int cid){ sortModel.GetRightData(cid); } @Override public void onRightFinish(RightBean bean) { iSortView.ShowRightData(bean); } }
Bean类
public class LeftBean { /** * msg : * code : 0 * data : [{"cid":1,"createtime":"2017-10-10T19:41:39","icon":"http://120.27.23.105/images/category/shop.png","ishome":1,"name":"京东超市"},{"cid":2,"createtime":"2017-10-10T19:41:39","icon":"http://120.27.23.105/images/category/qqg.png","ishome":1,"name":"全球购"},{"cid":3,"createtime":"2017-10-10T19:45:11","icon":"http://120.27.23.105/images/category/phone.png","ishome":1,"name":"手机数码"},{"cid":5,"createtime":"2017-10-10T20:12:03","icon":"http://120.27.23.105/images/category/man.png","ishome":1,"name":"男装"},{"cid":6,"createtime":"2017-10-10T20:12:03","icon":"http://120.27.23.105/images/category/girl.png","ishome":1,"name":"女装"},{"cid":7,"createtime":"2017-10-10T20:12:03","icon":"http://120.27.23.105/images/category/manshoe.png","ishome":1,"name":"男鞋"},{"cid":8,"createtime":"2017-10-10T20:12:03","icon":"http://120.27.23.105/images/category/girlshoe.png","ishome":1,"name":"女鞋"},{"cid":9,"createtime":"2017-10-10T20:12:03","icon":"http://120.27.23.105/images/category/shirt.png","ishome":1,"name":"内衣配饰"},{"cid":10,"createtime":"2017-10-10T20:12:03","icon":"http://120.27.23.105/images/category/bag.png","ishome":1,"name":"箱包手袋"},{"cid":11,"createtime":"2017-10-10T20:12:03","icon":"http://120.27.23.105/images/category/beauty.png","ishome":1,"name":"美妆个护"},{"cid":12,"createtime":"2017-10-10T20:12:03","icon":"http://120.27.23.105/images/category/jewel.png","ishome":1,"name":"钟表珠宝"},{"cid":13,"createtime":"2017-10-10T20:12:03","icon":"http://120.27.23.105/images/category/luxury.png","ishome":1,"name":"奢侈品"},{"cid":14,"createtime":"2017-10-10T20:12:03","icon":"http://120.27.23.105/images/category/computer.png","ishome":1,"name":"电脑办公"},{"cid":15,"createtime":"2017-09-29T10:13:48","icon":"http://120.27.23.105/images/icon.png","ishome":0,"name":"家用电器"},{"cid":16,"createtime":"2017-09-29T10:13:48","icon":"http://120.27.23.105/images/icon.png","ishome":0,"name":"食品生鲜"},{"cid":17,"createtime":"2017-09-29T10:13:48","icon":"http://120.27.23.105/images/icon.png","ishome":0,"name":"酒水饮料"},{"cid":18,"createtime":"2017-09-29T10:13:48","icon":"http://120.27.23.105/images/icon.png","ishome":0,"name":"母婴童装"},{"cid":19,"createtime":"2017-09-29T10:13:48","icon":"http://120.27.23.105/images/icon.png","ishome":0,"name":"玩具乐器"},{"cid":20,"createtime":"2017-09-29T10:13:48","icon":"http://120.27.23.105/images/icon.png","ishome":0,"name":"医药保健"}] */ private String msg; private String code; private List<DataBean> data; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { /** * cid : 1 * createtime : 2017-10-10T19:41:39 * icon : http://120.27.23.105/images/category/shop.png * ishome : 1 * name : 京东超市 */ private int cid; private String createtime; private String icon; private int ishome; private String name; public int getCid() { return cid; } public void setCid(int cid) { this.cid = cid; } public String getCreatetime() { return createtime; } public void setCreatetime(String createtime) { this.createtime = createtime; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public int getIshome() { return ishome; } public void setIshome(int ishome) { this.ishome = ishome; } public String getName() { return name; } public void setName(String name) { this.name = name; } } }
public class RightBean { /** * msg : 获取子分类成功 * code : 0 * data : [{"cid":"5","list":[{"icon":"http://120.27.23.105/images/icon.png","name":"修身休闲裤","pcid":14,"pscid":85},{"icon":"http://120.27.23.105/images/icon.png","name":"免烫休闲裤","pcid":14,"pscid":86},{"icon":"http://120.27.23.105/images/icon.png","name":"小脚休闲裤","pcid":14,"pscid":87},{"icon":"http://120.27.23.105/images/icon.png","name":"商务休闲裤","pcid":14,"pscid":88},{"icon":"http://120.27.23.105/images/icon.png","name":"九分裤","pcid":14,"pscid":89},{"icon":"http://120.27.23.105/images/icon.png","name":"卫裤","pcid":14,"pscid":90},{"icon":"http://120.27.23.105/images/icon.png","name":"哈伦裤","pcid":14,"pscid":91},{"icon":"http://120.27.23.105/images/icon.png","name":"针织裤","pcid":14,"pscid":92}],"name":"休闲裤","pcid":"14"},{"cid":"5","list":[{"icon":"http://120.27.23.105/images/icon.png","name":"加绒牛仔","pcid":15,"pscid":93},{"icon":"http://120.27.23.105/images/icon.png","name":"直筒牛仔","pcid":15,"pscid":94},{"icon":"http://120.27.23.105/images/icon.png","name":"修身牛仔","pcid":15,"pscid":95},{"icon":"http://120.27.23.105/images/icon.png","name":"纯色牛仔","pcid":15,"pscid":96},{"icon":"http://120.27.23.105/images/icon.png","name":"小脚牛仔","pcid":15,"pscid":97},{"icon":"http://120.27.23.105/images/icon.png","name":"弹力牛仔","pcid":15,"pscid":98},{"icon":"http://120.27.23.105/images/icon.png","name":"破洞牛仔","pcid":15,"pscid":99}],"name":"牛仔裤","pcid":"15"},{"cid":"5","list":[{"icon":"http://120.27.23.105/images/icon.png","name":"长袖衬衫","pcid":16,"pscid":100},{"icon":"http://120.27.23.105/images/icon.png","name":"短袖衬衫","pcid":16,"pscid":101},{"icon":"http://120.27.23.105/images/icon.png","name":"POLO衫","pcid":16,"pscid":102},{"icon":"http://120.27.23.105/images/icon.png","name":"卫衣","pcid":16,"pscid":103},{"icon":"http://120.27.23.105/images/icon.png","name":"纯棉衬衫","pcid":16,"pscid":104},{"icon":"http://120.27.23.105/images/icon.png","name":"针织衫","pcid":16,"pscid":105}],"name":"男士内搭","pcid":"16"},{"cid":"5","list":[{"icon":"http://120.27.23.105/images/icon.png","name":"夹克","pcid":17,"pscid":106},{"icon":"http://120.27.23.105/images/icon.png","name":"单西","pcid":17,"pscid":107},{"icon":"http://120.27.23.105/images/icon.png","name":"风衣","pcid":17,"pscid":108},{"icon":"http://120.27.23.105/images/icon.png","name":"真皮外套","pcid":17,"pscid":109},{"icon":"http://120.27.23.105/images/icon.png","name":"西服套装","pcid":17,"pscid":110},{"icon":"http://120.27.23.105/images/icon.png","name":"牛仔外套","pcid":17,"pscid":111}],"name":"男士外套","pcid":"17"}] */ private String msg; private String code; private List<DataBean> data; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { /** * cid : 5 * list : [{"icon":"http://120.27.23.105/images/icon.png","name":"修身休闲裤","pcid":14,"pscid":85},{"icon":"http://120.27.23.105/images/icon.png","name":"免烫休闲裤","pcid":14,"pscid":86},{"icon":"http://120.27.23.105/images/icon.png","name":"小脚休闲裤","pcid":14,"pscid":87},{"icon":"http://120.27.23.105/images/icon.png","name":"商务休闲裤","pcid":14,"pscid":88},{"icon":"http://120.27.23.105/images/icon.png","name":"九分裤","pcid":14,"pscid":89},{"icon":"http://120.27.23.105/images/icon.png","name":"卫裤","pcid":14,"pscid":90},{"icon":"http://120.27.23.105/images/icon.png","name":"哈伦裤","pcid":14,"pscid":91},{"icon":"http://120.27.23.105/images/icon.png","name":"针织裤","pcid":14,"pscid":92}] * name : 休闲裤 * pcid : 14 */ private String cid; private String name; private String pcid; private List<ListBean> list; public String getCid() { return cid; } public void setCid(String cid) { this.cid = cid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPcid() { return pcid; } public void setPcid(String pcid) { this.pcid = pcid; } public List<ListBean> getList() { return list; } public void setList(List<ListBean> list) { this.list = list; } public static class ListBean { /** * icon : http://120.27.23.105/images/icon.png * name : 修身休闲裤 * pcid : 14 * pscid : 85 */ private String icon; private String name; private int pcid; private int pscid; public ListBean(String icon, String name, int pcid, int pscid) { this.icon = icon; this.name = name; this.pcid = pcid; this.pscid = pscid; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPcid() { return pcid; } public void setPcid(int pcid) { this.pcid = pcid; } public int getPscid() { return pscid; } public void setPscid(int pscid) { this.pscid = pscid; } } } }
左右列表的adapter
public class LeftAdapter extends BaseAdapter{ // 数据源 LeftBean leftBean; // 上下文 Context context; public LeftAdapter(LeftBean leftBean, Context context) { this.leftBean = leftBean; this.context = context; } @Override public int getCount() { return leftBean.getData().size(); } @Override public Object getItem(int i) { return leftBean.getData().get(i); } @Override public long getItemId(int i) { return i; } /*接口回调*/ public interface ClickName{ void Clickname(int cid); } private ClickName clickName; public void setClickName(ClickName clickName) { this.clickName = clickName; } @Override public View getView(final int i, View view, ViewGroup viewGroup) { MyHolder holder; if (view == null){ view = LayoutInflater.from(context).inflate(R.layout.sort_left_item,null); holder = new MyHolder(); holder.tv = view.findViewById(R.id.sort_left_tv); view.setTag(holder); }else{ holder = (MyHolder) view.getTag(); } holder.tv.setText(leftBean.getData().get(i).getName()); holder.tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { clickName.Clickname(leftBean.getData().get(i).getCid()); } }); return view; } class MyHolder{ TextView tv; } }
public class RightAdapter extends BaseAdapter { // 数据源 RightBean rightBean; // 上下文 Context context; ArrayList<RightBean.DataBean.ListBean> right_lists; // 用于展示无图gridView //ArrayList<String> right_lists; public RightAdapter(RightBean rightBean, Context context) { this.rightBean = rightBean; this.context = context; } @Override public int getCount() { return rightBean.getData().size(); } @Override public Object getItem(int i) { return rightBean.getData().get(i); } @Override public long getItemId(int i) { return i; } public interface GetItemData{ void getItemData(String name,String pscid); } private GetItemData getItemData; public void GetItemData(GetItemData getItemData) { this.getItemData = getItemData; } @Override public View getView(int i, View view, ViewGroup viewGroup) { MyHolder holder; if (view == null) { view = LayoutInflater.from(context).inflate(R.layout.sort_right_item, null); holder = new MyHolder(); holder.tv = view.findViewById(R.id.sort_right_title); holder.gridView = view.findViewById(R.id.sort_right_grid); view.setTag(holder); } else { holder = (MyHolder) view.getTag(); } holder.tv.setText(rightBean.getData().get(i).getName()); right_lists = new ArrayList<>(); for (int j = 0; j < rightBean.getData().get(i).getList().size(); j++) { List<RightBean.DataBean.ListBean> list = rightBean.getData().get(i).getList(); RightBean.DataBean.ListBean listBean = list.get(j); right_lists.add(new RightBean.DataBean.ListBean(listBean.getIcon(), listBean.getName(), listBean.getPcid(), listBean.getPscid())); } // 无图的gridview //ArrayAdapter<String> adapter = new ArrayAdapter<>(context,android.R.layout.simple_list_item_1,right_lists); /*有图的gridview*/ final RightItemAdapter adapter = new RightItemAdapter(right_lists, context); holder.gridView.setAdapter(adapter); holder.gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { getItemData.getItemData(right_lists.get(i).getName(),right_lists.get(i).getPscid()+""); } }); return view; } class MyHolder { TextView tv; GridView gridView; } }
public class RightItemAdapter extends BaseAdapter { // 数据源 ArrayList<RightBean.DataBean.ListBean> lists; // 上下文 Context context; public RightItemAdapter(ArrayList<RightBean.DataBean.ListBean> lists, Context context) { this.lists = lists; this.context = context; } @Override public int getCount() { return lists.size(); } @Override public Object getItem(int i) { return lists.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(final int i, View view, ViewGroup viewGroup) { MyHolder holder; if (view == null) { view = LayoutInflater.from(context).inflate(R.layout.sort_right_grid_item, null); holder = new MyHolder(); holder.tv = view.findViewById(R.id.sort_right_grid_item_tv); holder.img = view.findViewById(R.id.sort_right_grid_item_img); view.setTag(holder); } else { holder = (MyHolder) view.getTag(); } Uri uri = Uri.parse(lists.get(i).getIcon()); holder.img.setImageURI(uri); holder.tv.setText(lists.get(i).getName()); return view; } class MyHolder { TextView tv; SimpleDraweeView img; } }
java代码就上面那些,下来就是xml布局文件(听说大牛都比较懒)
Main布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <ListView android:id="@+id/sort_left_listview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="2"></ListView> <ListView android:id="@+id/sort_right_listview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"></ListView> </LinearLayout>
sort_left_item布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="20dp" android:orientation="vertical"> <TextView android:background="@drawable/class_item_selector" android:id="@+id/sort_left_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp" android:text="左侧文字" android:textSize="30sp" android:textStyle="bold" /> </LinearLayout>
sort_right_grid_item布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:fresco="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/sort_right_grid_item_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="文字" android:textSize="20sp" /> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/sort_right_grid_item_img" android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center_horizontal" fresco:placeholderImage="@mipmap/ic_launcher" /> </LinearLayout>
sort_right_item布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:layout_width="10dp" android:layout_height="30dp" android:layout_marginLeft="5dp" android:layout_marginRight="10dp" android:src="@color/red" /> <TextView android:id="@+id/sort_right_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="测试" android:textSize="24sp" android:textStyle="bold" /> </LinearLayout> <com.bwie.www.shop_nsg1108.sort.view.MyGridView android:id="@+id/sort_right_grid" android:layout_width="match_parent" android:layout_height="wrap_content" android:numColumns="3" /> </LinearLayout>
用到的依赖也给大家附上:
// butterknife compile 'com.jakewharton:butterknife:8.4.0' apt 'com.jakewharton:butterknife-compiler:8.4.0'
// fresco compile 'com.facebook.fresco:fresco:0.12.0'
权限如下:
<!-- 网络 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 网络请求 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
分类页面的接口:
// 分类左侧接口 public static final String SORT_LEFT = "http://120.27.23.105/"; public static final String SORT_LEFT_PATH = "product/getCatagory"; // 分类右侧接口 public static final String SORT_RIGHT = "http://120.27.23.105/"; public static final String SORT_RIGHT_PATH = "product/getProductCatagory";
请求数据我用的retrofit+rxjava结合使用,代码也贴出来分享一下:
ApiService
// 分类 左侧接口 @GET Observable<LeftBean> getLeftData(@Url String url); // 分类 右侧接口 @POST Observable<RightBean> getRightData(@Url String url, @QueryMap HashMap<String,String> map);
SortLeftRetrofitFactory
public class SortLeftRetroFactory { private SortLeftRetroFactory() { } private static OkHttpClient httpClient = new OkHttpClient.Builder() .addInterceptor(new LoggingInterceptor()).connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build(); private static ApiServer retrofitService = new Retrofit.Builder() .baseUrl(Field.SORT_LEFT) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(httpClient) .build() .create(ApiServer.class); //单列模式 public static ApiServer getInstance() { return retrofitService; } }