1. 程式人生 > >Android RecyclerView瀑布流展示(OkHttp協議)

Android RecyclerView瀑布流展示(OkHttp協議)

一言不合就上圖

這裡寫圖片描述
OkHttp和recyclerView都是第三方提供的,so先注入依賴

//okhttp3網路請求協議
    compile 'com.squareup.okhttp3:okhttp:3.9.0'
//recyclerview控制元件
    compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
//Glide圖片載入
    compile 'com.github.bumptech.glide:glide:3.7.0'
//Gson  Json串解析工具
    compile 'com.google.code.gson:gson:2.8.1'

然後是寫MainActicity的主佈局:(注意最外層的佈局,方向orientation要寫成”vertical”,垂直後面會用到)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
android:id="@+id/recView" android:layout_width="match_parent" android:layout_height="match_parent"></android.support.v7.widget.RecyclerView> </LinearLayout>

和Item的子佈局rec_item:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width
="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<ImageView android:id="@+id/recIv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:scaleType="fitXY" android:src="@mipmap/ic_launcher_round" /> <TextView android:id="@+id/recTv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="14" android:gravity="center" android:singleLine="true" android:text="這是標題" android:textSize="22sp"/> </LinearLayout>

RecyclerView.Adapter介面卡類(此類我抽出來了)程式碼:

public class RecAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    //用來存放子條目高度的集合
    private List<Integer> heightList;
    //為了配合呼叫此介面卡的類的傳值呼叫,此倆個屬性是傳過來的上下文和集合,做下繫結而已
    //也就是有參構造器
    private MainActivity context;
    private List<LadyBean.NewslistBean> list;

    public RecAdapter(MainActivity context, List<LadyBean.NewslistBean> list) {
        this.context = context;
        this.list = list;

        //設定n個隨機數,這裡的隨機數,將設定給ImageView控制元件的高度上賦值
        //然後把這些個隨機數放到幾個,integer泛型的集合裡面
        heightList = new ArrayList<Integer>();
        for (int i = 0; i < list.size(); i++) {
            int height = new Random().nextInt(400) + 250;//[250,400)的隨機數
            //把隨機數放入集合裡
            heightList.add(height);
        }
    }


    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //填充佈局或渲染布局
        View view = View.inflate(context, R.layout.rec_item, null);
        //把渲染好的佈局放入自定義的ViewHolder裡,並return返回
        RecViewholder recViewholder = new RecViewholder(view);
        return recViewholder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        //繫結資料優化並強轉
        RecViewHolder recViewHolder = (RecViewHolder) holder;

        //獲取ViewGroup的可編輯佈局管理 ,然後給imageView控制元件賦可編輯的權利
        ViewGroup.LayoutParams params = recViewHolder.imageView.getLayoutParams();
        //然後設定高度從heightList集合裡面拿當前的隨機數,
        params.height = heightList.get(position);
        //把隨機數賦給imageView這個控制元件
        recViewHolder.imageView.setLayoutParams(params);
        //繫結給當前位置上的imageView控制元件
        holder.itemView.setTag(position);

        //給textView文字賦值
        recViewHolder.textView.setText(list.get(position).getTitle());
        //給圖片賦值
        Glide.with(context).load(list.get(position).getPicUrl()).into(recViewHolder.imageView);


    }

    @Override
    public int getItemCount() {
        //三元運算子:如果list不等於空返回list的長度:否則返回0
        //相當於if判空處理
        return list != null ? list.size() : 0;
    }
    //內部類自定義優化繼承ViewHolder,生成RecViewHolder的方法
    class RecViewHolder extends RecyclerView.ViewHolder {

        private final ImageView imageView;
        private final TextView textView;

        public RecViewHolder(View itemView) {
            super(itemView);
            //這裡的強制轉換,有人的studio不用強轉也不報錯也能出效果,可能是跟API版本有關吧
            imageView = (ImageView) itemView.findViewById(R.id.recIv);
            textView = (TextView) itemView.findViewById(R.id.recTv);
        }
    }
}

接下來就是MainActivity的內容了:


public class MainActivity extends AppCompatActivity {
    //快捷鍵:Ctrl+Alt+F  生成的全域性變數
    private RecyclerView recView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initData();
    }

    private void initData() {
        recView = (RecyclerView) findViewById(R.id.recView);
        //設定recyclerView的樣式:“線性佈局管理器”+引數是“當前上下文”
//        recView.setLayoutManager(new LinearLayoutManager(this));
        //瀑布流
        recView.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
        //new 出來OkHttp
        OkHttpClient ok = new OkHttpClient();
        //預設的GET請求方式
        Request request = new Request.Builder()
        .url("http://api.tianapi.com/meinv/?key=2a0024d1f7f558e09936f697580f1643&num=10")
        .build();
        Call call = ok.newCall(request);
        //用call呼叫enqueue非同步網路請求,
        call.enqueue(new Callback() {
            //new出來的介面卡,做了全域性,此處是快捷生成的
            private RecAdapter recAdapter;

            @Override
            public void onFailure(Call call, IOException e) {
                Toast.makeText(MainActivity.this,"請求失敗,失敗原因"+e,Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //此處是請求成功的方法,
                //response是請求過來的資料,把它轉成我們能看懂的String型別字串,方便下面的Gson.FromJson用
                String json = response.body().string();
                Log.e("++++++++++訪問到的結果:", json);
                //此處的Gson 就需要注入依賴包了
                Gson gson = new Gson();
                LadyBean ladyBean = gson.fromJson(json, LadyBean.class);
                //拿到bean裡面的集合
                List<LadyBean.NewslistBean> list = ladyBean.getNewslist();
                Log.e("+++++集合裡面的東西是:", list + "");
                //new 出來你的介面卡,傳一個上下文和集合
                recAdapter = new RecAdapter(MainActivity.this, list);
                //開啟返回主執行緒的執行緒,並且更新主UI,
                // 因為OKHttp預設在子執行緒請求資料,子執行緒不能更新UI,(會報錯或者無法顯示資料)
                //所以要手動開啟返回主執行緒的方法,並更新UI檢視
                //假如你是Fragment裡面,就要用:上下文再打點呼叫runOnUiThread()方法,否則打點調出不來
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //設定介面卡
                        recView.setAdapter(recAdapter);
                    }
                });

            }
        });
    }
}

這就OK了

強調幾點:
1我的Android studio是2.3.3版本,SDK用的v7…..26.+的
2為了顯得程式碼簡潔,導包我沒搬過來,so 你們自己導吧
3如果訪問網路:別忘記在AndroidManifest(註冊清單)新增網路許可權

<uses-permission android:name="android.permission.INTERNET" />