Android RecyclerView瀑布流展示(OkHttp协议)

来源:互联网 发布:网络ip冲突是什么意思? 编辑:程序博客网 时间:2024/06/06 03:56

一言不合就上图

这里写图片描述
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" />
原创粉丝点击