知乎日报客户端--知乎日报板块的实现

看完这一篇你应该学会:如何展示新闻资讯类,效果图:


上一篇讲的是 :知乎日报客户端--侧滑栏的实现

这一篇的知识点: Fragment的替换,Recylerview[adapter, holder]的使用,Okhttp,JSONObject解析json

还是先给布局:

zhihufragment.xml


RecylerView的item布局: zhihu_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tool="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:padding="5dp"
    android:layout_width="match_parent"
    android:layout_height="100dp">
    <ImageView
        android:layout_width="120dp"
        android:id="@+id/zhihu_img"
        android:scaleType="centerCrop"
        android:padding="10dp"
        android:layout_height="match_parent" />
    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:textSize="20sp"
            tools:text="wuiweqiyweuqiewwqwqwqew"
            android:id="@+id/zhihu_title"
            android:layout_weight="1"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            tools:text="知乎客户端"
            android:id="@+id/zhihu_from"/>
    </LinearLayout>
</LinearLayout>

由一个ImageView和两个TextView构成,ImageView用来显示知乎日报的图片,textview来显示标题和id。

接着是ZhihuFragment.java用来显示zhihu_fragment.xml的,并且在这个里面完成界面的初始化显示信息等:

public class ZhihuFragment extends Fragment {
    private Bitmap mBitmap;
    private List<News> mNews;
    private RecyclerView mRecyclerView;
    private ZhihuAdapter mAdapter;
    private boolean isGettingPre = false;
    private ProgressDialog mDialog;


    public static Fragment newInstance() {
        return new ZhihuFragment();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mDialog = new ProgressDialog(getActivity());
        mDialog.setTitle("加载中");
        mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        mDialog.setCancelable(false);
        Log.d("ZhihuFragmwnt","onCreate()");
        if(!CheckNetWork.checkNet(getActivity())){
            Toast.makeText(getActivity(),"网络连接失败...",Toast.LENGTH_SHORT).show();

        }
        mDialog.show();
        mAdapter = new ZhihuAdapter();
        final AsyncTask newsTask = new AsyncTask() {
            @Override
            protected List<News> doInBackground(Object[] objects) {
               mNews = Connect.getLatestNews(getActivity(),Connect.LATEST_URI);
               return mNews;
            }
            @Override
            protected void onPostExecute(Object o) {
                super.onPostExecute(o);
                mRecyclerView.setAdapter(mAdapter);
                mDialog.dismiss();
                Log.d("mNews length===>", ""+mNews.size());
            }
        };
       // newsTask.execute();
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                Log.d("ZhihuFragment","计时器在执行===");
                if(CheckNetWork.checkNet(getActivity())){
                    newsTask.execute();
                    this.cancel();
                }
            }
        },0,1000);
    }


    @RequiresApi(api = Build.VERSION_CODES.M)
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("ZhihuFragment","onCreateView()");
        View v = inflater.inflate(R.layout.zhihufragment, container, false);
        mRecyclerView = v.findViewById(R.id.recyler_view);
        final LinearLayoutManager manager = new LinearLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(manager);
        BitmapFactory.Options options = new BitmapFactory.Options();
        mBitmap = CalculateInSampleSize.decodeSampleBitmapFromRes(getResources(),R.drawable.g,240,200);
        mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(),DividerItemDecoration.VERTICAL));
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if(isGettingPre){
                    return;
                }
                Log.d("item的长度",""+ manager.getItemCount()+"\n 当前itemindex: " + manager.findLastVisibleItemPosition());
               if(manager.getItemCount() -manager.findLastVisibleItemPosition() < 2){
                 isGettingPre = true;
                   mDialog.show();
                   Log.d("Zhihu","只剩下4个item了");
                   AsyncTask task = new AsyncTask() {
                       @Override
                       protected List<News> doInBackground(Object[] objects) {
                           mNews = Connect.getPreNews();
                           //mAdapter.notifyDataSetChanged()
                           return mNews;
                       }
                       @Override
                       protected void onPostExecute(Object o) {
                           super.onPostExecute(o);
                           Log.d("重新加载mnews==:",""+mNews.size());
                           Log.d("count===> " ,""+manager.getItemCount()+"当前item下标===> " +manager.findLastVisibleItemPosition());
                           mAdapter.notifyDataSetChanged();
                           isGettingPre = false;
                            mDialog.dismiss();
                       }
                   };
                   task.execute();
               }
            }
        });
        return v;
    }

    private class ZhihuAdapter extends RecyclerView.Adapter<ZhihuAdapter.ViewHolder> {
        @Override
        public ZhihuAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(getActivity())
                    .inflate(R.layout.zhihu_list_item, parent, false);
            ViewHolder vh = new ViewHolder(v);
            return vh;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, final int position) {
            holder.mImageView.setImageBitmap(mNews.get(position).getBitmap());
            holder.mTitle.setText(mNews.get(position).getTitle());
            holder.mFrom.setText(mNews.get(position).getId());
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //Toast.makeText(getActivity(),"点击了recylerview",Toast.LENGTH_SHORT).show();
                   // News n = Connect.newsDetail(mNews.get(position));
                    AsyncTask task = new AsyncTask() {
                        @Override
                        protected String doInBackground(Object[] objects) {
                            String data = Connect.newsDetail(mNews.get(position));
                            return data;
                        }

                        @Override
                        protected void onPostExecute(Object o) {
                            super.onPostExecute(o);
                            Intent intent = new Intent(getActivity(), NewsInfoActivity.class);
                            intent.putExtra("data",String.valueOf(o));
                            startActivity(intent);
                        }
                    };
                    task.execute();
                }
            });
        }

        @Override
        public int getItemCount() {
            return mNews.size();
        }

        public class ViewHolder extends RecyclerView.ViewHolder {
            public ImageView mImageView;
            private TextView mTitle;
            private TextView mFrom;

            public ViewHolder(View itemView) {
                //super();
                super(itemView);
                mImageView = itemView.findViewById(R.id.zhihu_img);
                mTitle = itemView.findViewById(R.id.zhihu_title);
                mFrom = itemView.findViewById(R.id.zhihu_from);
//                itemView.setOnClickListener(new View.OnClickListener() {
//                    @Override
//                    public void onClick(View v) {
//                        Toast.makeText(getActivity(),"点击了recylerview",Toast.LENGTH_SHORT).show();
//                        Intent intent = new Intent(getActivity(), NewsInfoActivity.class);
//                        startActivity(intent);
//
//                    }
//                });
            }
        }

    }
}
下面会分几个部分来讲这个代码:

1. onCreate方法

打开时,显示一个dialog加载中,因为程序要从网络上获取数据,因为Android不允许在主线程中进行任何网络操作,所以这里使用的时AsyncTask异步进行获取,等到获取到数据后,就让dialog消失。

2. onCreateView方法

这个里面先inflate我的zhihufragment.xml布局,并且设置LayoutManager,还对onScroll方法进行侦听。

我是让当数据中只剩下4条结果未显示时就去自动拉去数据。用layoutmanager获取itemcount总数,和当前最后显示的下标位置lastitemposition,所以当itemcount - lastitemposition<5时便去获取数据,然后解析返回的json字符串,包装成news类后,再通知recylerview数据的改变,就实现下拉时会一直获取数据。

3.构建Adapter和holder

 private class ZhihuAdapter extends RecyclerView.Adapter<ZhihuAdapter.ViewHolder> {
        @Override
        public ZhihuAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(getActivity())
                    .inflate(R.layout.zhihu_list_item, parent, false);
            ViewHolder vh = new ViewHolder(v);
            return vh;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, final int position) {
            holder.mImageView.setImageBitmap(mNews.get(position).getBitmap());
            holder.mTitle.setText(mNews.get(position).getTitle());
            holder.mFrom.setText(mNews.get(position).getId());
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //Toast.makeText(getActivity(),"点击了recylerview",Toast.LENGTH_SHORT).show();
                   // News n = Connect.newsDetail(mNews.get(position));
                    AsyncTask task = new AsyncTask() {
                        @Override
                        protected String doInBackground(Object[] objects) {
                            String data = Connect.newsDetail(mNews.get(position));
                            return data;
                        }

                        @Override
                        protected void onPostExecute(Object o) {
                            super.onPostExecute(o);
                            Intent intent = new Intent(getActivity(), NewsInfoActivity.class);
                            intent.putExtra("data",String.valueOf(o));
                            startActivity(intent);
                        }
                    };
                    task.execute();
                }
            });
        }

        @Override
        public int getItemCount() {
            return mNews.size();
        }

        public class ViewHolder extends RecyclerView.ViewHolder {
            public ImageView mImageView;
            private TextView mTitle;
            private TextView mFrom;

            public ViewHolder(View itemView) {
                //super();
                super(itemView);
                mImageView = itemView.findViewById(R.id.zhihu_img);
                mTitle = itemView.findViewById(R.id.zhihu_title);
                mFrom = itemView.findViewById(R.id.zhihu_from);
//                itemView.setOnClickListener(new View.OnClickListener() {
//                    @Override
//                    public void onClick(View v) {
//                        Toast.makeText(getActivity(),"点击了recylerview",Toast.LENGTH_SHORT).show();
//                        Intent intent = new Intent(getActivity(), NewsInfoActivity.class);
//                        startActivity(intent);
//
//                    }
//                });
            }
        }

    }
创建内部类ZhihuAdapter继承Recylerview.Adapter

onCreateViewHolder用来加载并返回item条目

onBindViewHolder显示item的具体内容,并为itemView设置点击侦听,当点击打开新闻详情页

getItemCount返回item的长度

新闻详情页是 打开另一个activity,这个activity会显示一个WebView,里面加载html文件。

看一下获取数据部分:

 public static List<News> getLatestNews(Context context,String url) {
        OkHttpClient client = new OkHttpClient();  //创建okHttp对象
        Request request = new Request.Builder()    //创建request对象
                .url(url).build();
        try {
            Response response = client.newCall(request).execute();//得到Response对对象
            //response.
            if (response.isSuccessful()) {
                String result = response.body().string();
                JSONObject resultObj = new JSONObject(result);
                latestNews_date = resultObj.getString("date");
                Log.d(TAG,"latest date is==> " + latestNews_date );
                JSONArray storiesArr = resultObj.getJSONArray("stories");
                Log.d(TAG,"有"+storiesArr.length()+"个故事");
                JSONObject firstStory = new JSONObject(storiesArr.get(0).toString());
                Log.d("latest_remote_id===>",firstStory.getString("id"));
                Log.d("pre_news_id=>",SharePres.getLatestNewsId(context));
                if(firstStory.getString("id").equals(SharePres.getLatestNewsId(context))){
                    if(mNews.size() > 0){
                        return mNews;
                    }
                }
                mNews.clear();
                SharePres.setLatestNewsId(context,firstStory.getString("id"));
                for(int i=0;i<storiesArr.length();i++){
                    Log.d(TAG,"mNEws.size()===> " + mNews.size());
                    JSONObject stotyObj = new JSONObject( storiesArr.get(i).toString());
                    String id = stotyObj.getString("id");
                    String imgUrl = (String) stotyObj.getJSONArray("images").get(0);
                    String title = stotyObj.getString("title");
                    //Log.d(TAG,"img====> " + img + "\n id===> " + id + "\n title==> "+title);
                    Bitmap bitmap=getUrlBitmap(imgUrl);
                    News news = new News(id,title,bitmap);
                    mNews.add(news);
                }
                    return mNews;
            }
        } catch (IOException e) {
            Log.d(TAG, "连接失败", e);
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }
使用okhttp,然后获得返回内容应该用  response.body().string();
jsonobject解析放在list集合返回,通知recylerview数据发生改变。

获得从url获得bitmap方法:

 private static Bitmap getUrlBitmap(String imgUrl){
        Log.d("getBitmap===>", imgUrl);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(imgUrl).build();
        try {
            Response response = client.newCall(request).execute();
            if(response.isSuccessful()){
                Bitmap bitmap = BitmapFactory.decodeStream(response.body().byteStream());
                return bitmap;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
嗯。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值