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

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


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

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

还是先给布局:

zhihufragment.xml

知乎日报客户端--知乎日报板块的实现_第1张图片

RecylerView的item布局: zhihu_list_item.xml



    
    
        
        
    

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

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

public class ZhihuFragment extends Fragment {
    private Bitmap mBitmap;
    private List 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 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 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 {
        @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 {
        @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 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 " + 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;
    }
嗯。。


你可能感兴趣的:(知乎日报客户端各个功能的实现,Android知识碎碎片)