知乎日报客户端--知乎日报板块的实现
看完這一篇你應(yīng)該學(xué)會(huì):如何展示新聞資訊類,效果圖:
上一篇講的是 :知乎日?qǐng)?bào)客戶端--側(cè)滑欄的實(shí)現(xiàn)
這一篇的知識(shí)點(diǎn): 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"><ImageViewandroid:layout_width="120dp"android:id="@+id/zhihu_img"android:scaleType="centerCrop"android:padding="10dp"android:layout_height="match_parent" /><LinearLayoutandroid:layout_width="match_parent"android:orientation="vertical"android:layout_height="match_parent"><TextViewandroid:layout_width="match_parent"android:layout_height="0dp"android:textSize="20sp"tools:text="wuiweqiyweuqiewwqwqwqew"android:id="@+id/zhihu_title"android:layout_weight="1"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="right"tools:text="知乎客戶端"android:id="@+id/zhihu_from"/></LinearLayout> </LinearLayout>由一個(gè)ImageView和兩個(gè)TextView構(gòu)成,ImageView用來(lái)顯示知乎日?qǐng)?bào)的圖片,textview來(lái)顯示標(biāo)題和id。
接著是ZhihuFragment.java用來(lái)顯示zhihu_fragment.xml的,并且在這個(gè)里面完成界面的初始化顯示信息等:
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();}@Overridepublic 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(),"網(wǎng)絡(luò)連接失敗...",Toast.LENGTH_SHORT).show();}mDialog.show();mAdapter = new ZhihuAdapter();final AsyncTask newsTask = new AsyncTask() {@Overrideprotected List<News> doInBackground(Object[] objects) {mNews = Connect.getLatestNews(getActivity(),Connect.LATEST_URI);return mNews;}@Overrideprotected 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() {@Overridepublic void run() {Log.d("ZhihuFragment","計(jì)時(shí)器在執(zhí)行===");if(CheckNetWork.checkNet(getActivity())){newsTask.execute();this.cancel();}}},0,1000);}@RequiresApi(api = Build.VERSION_CODES.M)@Nullable@Overridepublic 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() {@Overridepublic void onScrolled(RecyclerView recyclerView, int dx, int dy) {super.onScrolled(recyclerView, dx, dy);if(isGettingPre){return;}Log.d("item的長(zhǎng)度",""+ manager.getItemCount()+"\n 當(dāng)前itemindex: " + manager.findLastVisibleItemPosition());if(manager.getItemCount() -manager.findLastVisibleItemPosition() < 2){isGettingPre = true;mDialog.show();Log.d("Zhihu","只剩下4個(gè)item了");AsyncTask task = new AsyncTask() {@Overrideprotected List<News> doInBackground(Object[] objects) {mNews = Connect.getPreNews();//mAdapter.notifyDataSetChanged()return mNews;}@Overrideprotected void onPostExecute(Object o) {super.onPostExecute(o);Log.d("重新加載mnews==:",""+mNews.size());Log.d("count===> " ,""+manager.getItemCount()+"當(dāng)前item下標(biāo)===> " +manager.findLastVisibleItemPosition());mAdapter.notifyDataSetChanged();isGettingPre = false;mDialog.dismiss();}};task.execute();}}});return v;}private class ZhihuAdapter extends RecyclerView.Adapter<ZhihuAdapter.ViewHolder> {@Overridepublic 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;}@Overridepublic 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() {@Overridepublic void onClick(View v) {//Toast.makeText(getActivity(),"點(diǎn)擊了recylerview",Toast.LENGTH_SHORT).show();// News n = Connect.newsDetail(mNews.get(position));AsyncTask task = new AsyncTask() {@Overrideprotected String doInBackground(Object[] objects) {String data = Connect.newsDetail(mNews.get(position));return data;}@Overrideprotected void onPostExecute(Object o) {super.onPostExecute(o);Intent intent = new Intent(getActivity(), NewsInfoActivity.class);intent.putExtra("data",String.valueOf(o));startActivity(intent);}};task.execute();}});}@Overridepublic 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(),"點(diǎn)擊了recylerview",Toast.LENGTH_SHORT).show(); // Intent intent = new Intent(getActivity(), NewsInfoActivity.class); // startActivity(intent); // // } // });}}} }下面會(huì)分幾個(gè)部分來(lái)講這個(gè)代碼:1. onCreate方法
打開時(shí),顯示一個(gè)dialog加載中,因?yàn)槌绦蛞獜木W(wǎng)絡(luò)上獲取數(shù)據(jù),因?yàn)锳ndroid不允許在主線程中進(jìn)行任何網(wǎng)絡(luò)操作,所以這里使用的時(shí)AsyncTask異步進(jìn)行獲取,等到獲取到數(shù)據(jù)后,就讓dialog消失。
2. onCreateView方法
這個(gè)里面先inflate我的zhihufragment.xml布局,并且設(shè)置LayoutManager,還對(duì)onScroll方法進(jìn)行偵聽。
我是讓當(dāng)數(shù)據(jù)中只剩下4條結(jié)果未顯示時(shí)就去自動(dòng)拉去數(shù)據(jù)。用layoutmanager獲取itemcount總數(shù),和當(dāng)前最后顯示的下標(biāo)位置lastitemposition,所以當(dāng)itemcount - lastitemposition<5時(shí)便去獲取數(shù)據(jù),然后解析返回的json字符串,包裝成news類后,再通知recylerview數(shù)據(jù)的改變,就實(shí)現(xiàn)下拉時(shí)會(huì)一直獲取數(shù)據(jù)。
3.構(gòu)建Adapter和holder
private class ZhihuAdapter extends RecyclerView.Adapter<ZhihuAdapter.ViewHolder> {@Overridepublic 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;}@Overridepublic 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() {@Overridepublic void onClick(View v) {//Toast.makeText(getActivity(),"點(diǎn)擊了recylerview",Toast.LENGTH_SHORT).show();// News n = Connect.newsDetail(mNews.get(position));AsyncTask task = new AsyncTask() {@Overrideprotected String doInBackground(Object[] objects) {String data = Connect.newsDetail(mNews.get(position));return data;}@Overrideprotected void onPostExecute(Object o) {super.onPostExecute(o);Intent intent = new Intent(getActivity(), NewsInfoActivity.class);intent.putExtra("data",String.valueOf(o));startActivity(intent);}};task.execute();}});}@Overridepublic 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(),"點(diǎn)擊了recylerview",Toast.LENGTH_SHORT).show(); // Intent intent = new Intent(getActivity(), NewsInfoActivity.class); // startActivity(intent); // // } // });}}}創(chuàng)建內(nèi)部類ZhihuAdapter繼承Recylerview.AdapteronCreateViewHolder用來(lái)加載并返回item條目
onBindViewHolder顯示item的具體內(nèi)容,并為itemView設(shè)置點(diǎn)擊偵聽,當(dāng)點(diǎn)擊打開新聞詳情頁(yè)
getItemCount返回item的長(zhǎng)度
。
新聞詳情頁(yè)是 打開另一個(gè)activity,這個(gè)activity會(huì)顯示一個(gè)WebView,里面加載html文件。
看一下獲取數(shù)據(jù)部分:
public static List<News> getLatestNews(Context context,String url) {OkHttpClient client = new OkHttpClient(); //創(chuàng)建okHttp對(duì)象Request request = new Request.Builder() //創(chuàng)建request對(duì)象.url(url).build();try {Response response = client.newCall(request).execute();//得到Response對(duì)對(duì)象//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()+"個(gè)故事");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,然后獲得返回內(nèi)容應(yīng)該用? response.body().string();jsonobject解析放在list集合返回,通知recylerview數(shù)據(jù)發(fā)生改變。
獲得從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;}嗯。。
總結(jié)
以上是生活随笔為你收集整理的知乎日报客户端--知乎日报板块的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《预训练周刊》第67期: ChatGPT
- 下一篇: 华为交换机ip地址与MAC地址绑定(全局