1.先添加需要的依賴
compile 'com.squareup.okhttp3:okhttp:3.3.0' compile 'com.github.bumptech.glide:glide:3.7.0'
2.添加網絡權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET"/>
3.HttPConfig類
package com.bw.lenovo.my_fenlei.http; /** * 接口存放類 */ public class HttpConfig { //左側列表接口 public static String Left_url = "https://www.zhaoapi.cn/product/getCatagory"; //右側列表接口 public static String right_url = "https://www.zhaoapi.cn/product/getProductCatagory"; }
4.根據接口去解析一鍵解析Bean類(LeftBean)和(RightZiBean)
5.寫okHttp網絡請求框架 OkHttpUtils
package com.bw.lenovo.my_fenlei.http; import android.os.Handler; import android.os.Message; import java.io.IOException; import java.util.Map; import java.util.Set; import okhttp3.Call; import okhttp3.Callback; import okhttp3.FormBody; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; public class OKHttpUtils { private static OKHttpUtils okHttpUtils = null; private OnLoadLinstener onLoadLinstener; private MyViewHolder myviewholder = new MyViewHolder(); public static OKHttpUtils getInStance() { if (okHttpUtils == null) { okHttpUtils = new OKHttpUtils(); } return okHttpUtils; } public void OkGet(String url) { OkHttpClient okHttpClient = new OkHttpClient(); Request request = new Request.Builder().url(url).build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Message message = myviewholder.obtainMessage(); message.what = 1; message.obj = e.getMessage(); myviewholder.sendMessage(message); } @Override public void onResponse(Call call, Response response) throws IOException { Message message = myviewholder.obtainMessage(); message.what = 0; message.obj = response.body().string(); myviewholder.sendMessage(message); } }); } public void OKPost(String url, Map<String, String> params) { OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new MyIntercepter()).build(); FormBody.Builder builder = new FormBody.Builder(); if (params != null) { Set<String> keys = params.keySet(); for (String key : keys) { String value = params.get(key); builder.add(key, value); } } FormBody body = builder.build(); Request request = new Request.Builder().url(url).post(body).build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Message message = myviewholder.obtainMessage(); message.what = 1; message.obj = e.getMessage(); myviewholder.sendMessage(message); } @Override public void onResponse(Call call, Response response) throws IOException { Message message = myviewholder.obtainMessage(); message.what = 0; message.obj = response.body().string(); myviewholder.sendMessage(message); } }); } class MyViewHolder extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: String error = (String) msg.obj; onLoadLinstener.onLoadError(error); break; case 0: String json = (String) msg.obj; onLoadLinstener.onLoadSucess(json); break; } } } //攔截器 class MyIntercepter implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); RequestBody body = request.body(); //判斷如果是formBody if (body instanceof FormBody) { FormBody.Builder builder = new FormBody.Builder(); for (int i = 0; i < ((FormBody) body).size(); i++) { String key = ((FormBody) body).name(i); String value = ((FormBody) body).value(i); builder.add(key, value); } builder.add("source", "android"); FormBody newbody = builder.build(); Request request1 = request.newBuilder().post(newbody).build(); Response response = chain.proceed(request1); return response; } return null; } } public interface OnLoadLinstener { void onLoadSucess(String json); void onLoadError(String error); } public void SetOnLoadLinstener(OnLoadLinstener onLoadLinstener) { this.onLoadLinstener = onLoadLinstener; } }
一、<1>mainActivity的佈局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context="com.bw.lenovo.my_fenlei.MainActivity"> <ListView android:id="@+id/fenlei_listview1" android:layout_width="100dp" android:layout_height="match_parent" android:divider="#00000000" android:dividerHeight="18dp"></ListView> <ListView android:id="@+id/fenlei_listview2" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </LinearLayout>
<2>、左側列表的佈局
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/item_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:dividerHeight="10dp" android:gravity="center" android:text="測試" android:textSize="20sp"> </TextView>
<3>、右側列表的佈局
<?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/zifenlei" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="子分類" android:textSize="20sp" /> <com.bw.lenovo.my_fenlei.view.MyGridView ----》自定義的MyGridView類(自己測量的模式) android:id="@+id/zi_gridview" android:layout_width="match_parent" android:layout_height="match_parent" android:numColumns="3"></com.bw.lenovo.my_fenlei.view.MyGridView> </LinearLayout>
<4>、右側列表中的Gridview佈局
<?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:layout_gravity="center" android:orientation="vertical"> <ImageView android:id="@+id/gridViewPic" android:layout_width="50dp" android:layout_height="50dp" android:src="@mipmap/ic_launcher" /> <TextView android:id="@+id/gridview_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="測試" android:textSize="20sp" /> </LinearLayout>
二、view包下 創建IView接口 ---》別忘了去mainAcivity實現
package com.bw.lenovo.my_fenlei.view; import com.bw.lenovo.my_fenlei.model.LeftBean; import com.bw.lenovo.my_fenlei.model.RightZiBean; import java.util.List; public interface IView { //實現展示左側列表的功能 void showLeftListView(List<LeftBean.DataBean> list); //=展示右側數據 void showRightLisstView(List<RightZiBean.DataBean> data, int position); //獲取cid int getCid(int poistion); }
三、(1):model包下 創建IModel接口
package com.bw.lenovo.my_fenlei.model; import java.util.Map; public interface IModel { //展示左側數據 void showLeftList(String url, Map<String,String> params,GetLeftListViewListener getLeftListViewListener); //根據cid獲取右側商品數據列表 void showRightList(String url,Map<String,String> params,GetRightZiFenLeiLintener getRightZiFenLeiLintener); }
(2):獲取左側列表的監聽事件 GetLeftListViewListener
package com.bw.lenovo.my_fenlei.model; /** * h獲取左側數據的監聽事件 */ public interface GetLeftListViewListener { //成功 void getLeftSuccess(String json); //失敗 void getLeftError(String error); }
(3):獲取右側列表的監聽事件
package com.bw.lenovo.my_fenlei.model; /** * 獲取右側列表的監聽事件 */ public interface GetRightZiFenLeiLintener { // 成功 void getZiSuccess(String json); //失敗 void getZiError(String error); }
(4):model包下 創建IModelImpI類-》去實現IModel接口
package com.bw.lenovo.my_fenlei.model; import android.util.Log; import com.bw.lenovo.my_fenlei.http.OKHttpUtils; import java.util.Map; /** * model的具體實現類 */ public class IModelImpI implements IModel { private static final String TAG = "IModelImpI=========="; /** * 展示左側數據的方法 * @param url * @param params * @param getLeftListViewListener */ @Override public void showLeftList(String url, Map<String, String> params, final GetLeftListViewListener getLeftListViewListener) { OKHttpUtils inStance = OKHttpUtils.getInStance(); inStance.OKPost(url, params); inStance.SetOnLoadLinstener(new OKHttpUtils.OnLoadLinstener() { @Override public void onLoadSucess(String json) { getLeftListViewListener.getLeftSuccess(json); } @Override public void onLoadError(String error) { getLeftListViewListener.getLeftError(error); } }); } /** * 展示右側數據的方法 * @param url * @param params * @param getRightZiFenLeiLintener */ @Override public void showRightList(String url, Map<String, String> params, final GetRightZiFenLeiLintener getRightZiFenLeiLintener) { OKHttpUtils inStance = OKHttpUtils.getInStance(); inStance.OKPost(url, params); inStance.SetOnLoadLinstener(new OKHttpUtils.OnLoadLinstener() { @Override public void onLoadSucess(String json) { Log.d(TAG, "右側數據====" + json); getRightZiFenLeiLintener.getZiSuccess(json); } @Override public void onLoadError(String error) { getRightZiFenLeiLintener.getZiError(error); } }); } }
四、(1):presenter包下 創建IPresenter接口
package com.bw.lenovo.my_fenlei.presenter; import com.bw.lenovo.my_fenlei.model.IModel; import com.bw.lenovo.my_fenlei.view.IView; public interface IPresenter { //展示左側列表 void showLeftFenlei(IModel iModel, IView iView); //展示右側 void showRightFenlei(IModel iModel, IView iView,int poistion); }
(2):presenter包下 創建IPresenterImpI類-》實現IPresenter接口
package com.bw.lenovo.my_fenlei.presenter; import android.util.Log; import com.bw.lenovo.my_fenlei.http.HttpConfig; import com.bw.lenovo.my_fenlei.model.GetLeftListViewListener; import com.bw.lenovo.my_fenlei.model.GetRightZiFenLeiLintener; import com.bw.lenovo.my_fenlei.model.IModel; import com.bw.lenovo.my_fenlei.model.LeftBean; import com.bw.lenovo.my_fenlei.model.RightZiBean; import com.bw.lenovo.my_fenlei.view.IView; import com.google.gson.Gson; import java.util.HashMap; import java.util.List; import java.util.Map; import static android.content.ContentValues.TAG; /** * IPrsenter的具體實現類 */ public class IPresenterImpI implements IPresenter { //展示左側分類頁面 @Override public void showLeftFenlei(IModel iModel, final IView iView) { iModel.showLeftList(HttpConfig.Left_url, null, new GetLeftListViewListener() { @Override public void getLeftSuccess(String json) { Log.d(TAG, "getLeftSuccess左側數據=======" + json); Gson gson = new Gson(); LeftBean leftBean = gson.fromJson(json, LeftBean.class); List<LeftBean.DataBean> list = leftBean.getData(); iView.showLeftListView(list); } @Override public void getLeftError(String error) { } }); } /** * 展示分類的右側頁面 * @param iModel * @param iView * @param poistion */ @Override public void showRightFenlei(IModel iModel, final IView iView, final int poistion) { //實例化map Map<String, String> map = new HashMap<>(); //添加參數cid map.put("cid",iView.getCid(poistion)+""); iModel.showRightList(HttpConfig.right_url, map,new GetRightZiFenLeiLintener() { @Override public void getZiSuccess(String json) { Log.d(TAG,"getZiSuccess右側數據======="+json); //gson解析數據 Gson gson = new Gson(); RightZiBean rightZiBean = gson.fromJson(json, RightZiBean.class); List<RightZiBean.DataBean> list1 = rightZiBean.getData(); iView.showRightLisstView(list1,poistion); } @Override public void getZiError(String error) { } }); } }
五、展示左側列表的適配器 MyLeftAdapter
package com.bw.lenovo.my_fenlei.model; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.bw.lenovo.my_fenlei.R; import java.util.List; /**左側列表的適配器 */ public class MyLeftAdapter extends BaseAdapter { /** * 傳過來的上下文,和集合 */ private final Context context; private final List<LeftBean.DataBean> list; public MyLeftAdapter(Context context, List<LeftBean.DataBean> list) { this.context = context; this.list = list; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View view, ViewGroup viewGroup) { /** * 優化 */ MyViewHolder myViewHolder = null; if (view == null) { view = View.inflate(context, R.layout.item_listview1_layout, null); TextView item_text = view.findViewById(R.id.item_text); myViewHolder = new MyViewHolder(item_text); view.setTag(myViewHolder); } else { myViewHolder = (MyViewHolder) view.getTag(); } myViewHolder.getTv_text().setText(list.get(i).getName()); return view; } /** * viewholder類 */ class MyViewHolder { TextView tv_text; public MyViewHolder(TextView tv_text) { this.tv_text = tv_text; } public TextView getTv_text() { return tv_text; } public void setTv_text(TextView tv_text) { this.tv_text = tv_text; } } }
六、展示右側列表的適配器 MyRightAdapter
package com.bw.lenovo.my_fenlei.model; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.TextView; import com.bw.lenovo.my_fenlei.R; import com.bw.lenovo.my_fenlei.view.MyGridView; import java.util.List; /** * 展示右側數據的適配器 */ public class MyRightAdapter extends BaseAdapter { /** * 傳過來的上下文好,和集合 */ private final Context context; private final List<RightZiBean.DataBean> data; public MyRightAdapter(Context context, List<RightZiBean.DataBean> data) { this.context = context; this.data = data; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View view, ViewGroup viewGroup) { //優化 MyviewHolder myviewHolder = null; if (view == null) { view = View.inflate(context, R.layout.item_listview2_layout, null); TextView zifenlei = view.findViewById(R.id.zifenlei); MyGridView zi_gridview = view.findViewById(R.id.zi_gridview); myviewHolder = new MyviewHolder(zifenlei, zi_gridview); view.setTag(myviewHolder); } else { myviewHolder = (MyviewHolder) view.getTag(); } myviewHolder.getTextView().setText(data.get(i).getName()); //GridView的適配器---》需要在寫一個GridView的適配器加載過來 MyGridViewAdapter myGridViewAdapter = new MyGridViewAdapter(context, data.get(i).getList()); //把寫好的GridView適配器加載進來 myviewHolder.getGridView().setAdapter(myGridViewAdapter); return view; } //創建viewholde class MyviewHolder { private TextView textView; private MyGridView gridView; public MyviewHolder(TextView textView, GridView gridView) { this.textView = textView; this.gridView = (MyGridView) gridView; } public TextView getTextView() { return textView; } public void setTextView(TextView textView) { this.textView = textView; } public GridView getGridView() { return gridView; } public void setGridView(GridView gridView) { this.gridView = (MyGridView) gridView; } } }
七、最裏面GridView列表的適配器 MyGridViewAdapter
package com.bw.lenovo.my_fenlei.model; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; import com.bw.lenovo.my_fenlei.R; import java.util.List; public class MyGridViewAdapter extends BaseAdapter { /** * context 上下文傳過來 * 這個集合是子分類bean最裏層的集合---》DataBean---》ListBean */ Context context; List<RightZiBean.DataBean.ListBean> list; public MyGridViewAdapter(Context context, List<RightZiBean.DataBean.ListBean> list) { this.context = context; this.list = list; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View view, ViewGroup viewGroup) { MyViewHolder myViewHolder = null; if (view == null) { view = View.inflate(context, R.layout.item_girdview_layout, null); ImageView gridViewPic = view.findViewById(R.id.gridViewPic); TextView gridview_tv = view.findViewById(R.id.gridview_tv); myViewHolder = new MyViewHolder(gridViewPic, gridview_tv); view.setTag(myViewHolder); } else { myViewHolder = (MyViewHolder) view.getTag(); } // Glide加載圖片 Glide.with(context).load(list.get(i).getIcon()).into(myViewHolder.getImageview()); //給textview賦值 myViewHolder.getTextview().setText(list.get(i).getName()); return view; } //創建gridview的viewholder class MyViewHolder { private ImageView imageview; private TextView textview; public MyViewHolder(ImageView imageview, TextView textview) { this.imageview = imageview; this.textview = textview; } public ImageView getImageview() { return imageview; } public void setImageview(ImageView imageview) { this.imageview = imageview; } public TextView getTextview() { return textview; } public void setTextview(TextView textview) { this.textview = textview; } } }
八、MainActivity類
package com.bw.lenovo.my_fenlei; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import com.bw.lenovo.my_fenlei.model.IModelImpI; import com.bw.lenovo.my_fenlei.model.LeftBean; import com.bw.lenovo.my_fenlei.model.MyLeftAdapter; import com.bw.lenovo.my_fenlei.model.MyRightAdapter; import com.bw.lenovo.my_fenlei.model.RightZiBean; import com.bw.lenovo.my_fenlei.presenter.IPresenterImpI; import com.bw.lenovo.my_fenlei.view.IView; import java.util.List; public class MainActivity extends AppCompatActivity implements IView { private ListView fenlei_listview1; private ListView fenlei_listview2; List<LeftBean.DataBean> list; private IPresenterImpI iPresenterImpI; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化數據 initviews(); // 調用presenter iPresenterImpI = new IPresenterImpI(); iPresenterImpI.showLeftFenlei(new IModelImpI(), this); } private void initviews() { fenlei_listview1 = (ListView) findViewById(R.id.fenlei_listview1); fenlei_listview2 = (ListView) findViewById(R.id.fenlei_listview2); //左側列表的條目點擊事件 fenlei_listview1.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { iPresenterImpI.showRightFenlei(new IModelImpI(), MainActivity.this,i); } }); } //展示左側列表 @Override public void showLeftListView(List<LeftBean.DataBean> list) { this.list = list; //實例化左側列表適配器 MyLeftAdapter myLeftAdapter = new MyLeftAdapter(MainActivity.this, list); //設置適配器 fenlei_listview1.setAdapter(myLeftAdapter); //默認將第一個分類展示出來 iPresenterImpI.showRightFenlei(new IModelImpI(),MainActivity.this,0); } //顯示右側數據 @Override public void showRightLisstView(List<RightZiBean.DataBean> data, int poistion) { Log.d("MainActivity", "右側數據"); //實例化右側列表適配器 MyRightAdapter myRightAdapter = new MyRightAdapter(this, data); //設置適配器 fenlei_listview2.setAdapter(myRightAdapter); } /** * 獲取參數cid * @param poistion * @return */ @Override public int getCid(int poistion) { int cid = list.get(poistion).getCid(); return cid; } }
九、讓數據整齊排列 自定義GridView (改變測量模式)
package com.bw.lenovo.my_fenlei.view; import android.content.Context; import android.icu.util.Measure; import android.util.AttributeSet; import android.widget.GridView; /** * 自定義Gridview 改變他的測量模式‘ */ public class MyGridView extends GridView { public MyGridView(Context context) { super(context); } public MyGridView(Context context, AttributeSet attrs) { super(context, attrs); } public MyGridView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } //改變測量模式 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //需要改變的只是高度的測量模式 int heightmes = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, heightmes); } }