国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

安卓開(kāi)發(fā)筆記——打造屬于自己的博客園APP(三)

2019-11-15 01:15:10
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
安卓開(kāi)發(fā)筆記——打造屬于自己的博客園APP(三)

  在上一篇文章《安卓開(kāi)發(fā)筆記——打造屬于自己的博客園APP(二)》中,我們基本上實(shí)現(xiàn)了主界面的搭建,網(wǎng)絡(luò)框架的搭建,各博客列表頁(yè)面的展示包括更新效果,對(duì)圖片做了三級(jí)緩存處理(后面會(huì)把文章,新聞做成離線(xiàn)閃存,實(shí)現(xiàn)無(wú)網(wǎng)絡(luò)也能照常瀏覽)。

  今天來(lái)講講博客詳情頁(yè)和評(píng)論頁(yè)面的實(shí)現(xiàn),國(guó)際慣例,先上效果圖:(動(dòng)態(tài)圖片比較大,加載需要點(diǎn)時(shí)間)

 

  這里說(shuō)下,關(guān)于上篇文章xml的解析,我后來(lái)查了下確實(shí)有一些方便解析的工具,例如:FastXML,Xstram等且效率更高,這里是在它的官方找到的一張數(shù)據(jù)圖:

文章里我就還是先采用原生的pull解析了,等重構(gòu)代碼時(shí)候再換上工具類(lèi)吧,先把項(xiàng)目做完?!?/p>

  好了,廢話(huà)不多說(shuō)了,直接進(jìn)入主題:

1、關(guān)于RecyclerView的點(diǎn)擊事件

  首先先來(lái)說(shuō)下關(guān)于RecyclerView的點(diǎn)擊監(jiān)聽(tīng)事件,在上篇文章提到,RecyclerView是ListView升級(jí)版,顧名思義它是為效率而生的,它不關(guān)心多余的任何事情,比如Item項(xiàng)的動(dòng)作監(jiān)聽(tīng),Item項(xiàng)的分割線(xiàn),Item項(xiàng)的添加動(dòng)畫(huà)效果,只專(zhuān)注于數(shù)據(jù)的展示實(shí)現(xiàn),相比ListView它更符合軟件設(shè)計(jì)原則,更加解耦。

  上面提到它不關(guān)心Item項(xiàng)的動(dòng)作監(jiān)聽(tīng),很自然,它沒(méi)有和ListView控件一樣提供類(lèi)似setOnItemClickListener這種監(jiān)聽(tīng)方法,需要我們自己來(lái)實(shí)現(xiàn),那么很自然的,我們會(huì)選擇在Adapter里去設(shè)置監(jiān)聽(tīng)事件,關(guān)于RecyclerView不熟悉的朋友可以先看下這篇文章:http://blog.csdn.net/lmj623565791/article/details/45059587

  首先我們?cè)贏dapter設(shè)置一個(gè)點(diǎn)擊回調(diào)接口,并提供setter方法:

 1     /** 2      * 自定義點(diǎn)擊回調(diào)接口 3      */ 4     public interface RecyclerViewListener { 5         void setOnclickListener(View view, int pos); 6     } 7  8     PRivate RecyclerViewListener mRecyclerViewListener; 9 10     /**11      * 提供setter方法12      *13      * @param recyclerViewListener14      */15     public void setRecyclerViewListener(RecyclerViewListener recyclerViewListener) {16         this.mRecyclerViewListener = recyclerViewListener;17     }

  然后我們?cè)趏nBindViewHolder中設(shè)置監(jiān)聽(tīng)事件:

1         //設(shè)置點(diǎn)擊監(jiān)聽(tīng)2         viewholder.itemView.setTag(i);3         viewholder.mMore.setTag(Integer.MAX_VALUE);4         viewholder.itemView.setOnClickListener(new ItemClick());5         viewholder.mMore.setOnClickListener(new ItemClick());

  再來(lái)個(gè)實(shí)現(xiàn)接口:

    /**     * 點(diǎn)擊事件實(shí)現(xiàn)類(lèi)     */    public class ItemClick implements View.OnClickListener{        @Override        public void onClick(View v) {            if(mRecyclerViewListener!=null){                mRecyclerViewListener.setOnclickListener(v,(int)v.getTag());            }        }    }

  這樣子,我們就可以在我們的博客列表頁(yè)面設(shè)置點(diǎn)擊事件了,關(guān)于下面的showPopUpMenu是一個(gè)點(diǎn)擊彈出窗口,可以實(shí)現(xiàn)收藏博文和關(guān)注博主的功能,我們下一篇文章會(huì)提到。這里我們實(shí)現(xiàn)當(dāng)點(diǎn)擊RecyclerView條目的時(shí)候會(huì)通過(guò)Intent傳遞Blog對(duì)象到博文詳情頁(yè)面。

 1         //設(shè)置條目點(diǎn)擊監(jiān)聽(tīng) 2         mBlogListAdapter.setRecyclerViewListener(new BlogListAdapter.RecyclerViewListener() { 3             @Override 4             public void setOnclickListener(View view, int pos) { 5  6                 if (view.getId() == R.id.ib_more) { 7                     //點(diǎn)擊菜單按鈕 8                     showPopUpMenu(view, pos); 9                 } else {10                     //點(diǎn)擊條目,傳遞對(duì)象11                     Intent intent = new Intent();12                     intent.setClass(getActivity(), BlogContentActivity.class);13                     Bundle bundle = new Bundle();14                     bundle.putSerializable("blog", mBlogs.get(pos));15                     intent.putExtras(bundle);16                     startActivity(intent);17                 }18             }19         });

2、關(guān)于博文詳情頁(yè)面的實(shí)現(xiàn)

  這里是關(guān)于博文詳情的接口:http://wcf.open.VEVb.com/blog/post/body/{POSTID}(POSTID代表文章Id)

這里是關(guān)于博文詳情的XML解析代碼:

 1 package com.lcw.rabbit.myblog.parser; 2  3 import org.xmlpull.v1.XmlPullParser; 4 import org.xmlpull.v1.XmlPullParserException; 5 import org.xmlpull.v1.XmlPullParserFactory; 6  7 import java.io.IOException; 8 import java.io.InputStream; 9 10 /**11  * 對(duì)博文詳情xml數(shù)據(jù)的解析12  * Created by Lichenwei13  * Date: 2015-08-1714  * Time: 13:3215  */16 public class BlogContentXmlParser {17 18 19     /**20      * 用于解析博文詳情的xml,返回Avatar的List集合對(duì)象21      *22      * @param inputStream23      * @param encode24      * @return25      * @throws XmlPullParserException26      * @throws IOException27      */28     public static String getBlogContent(InputStream inputStream, String encode) throws XmlPullParserException, IOException {29 30         String info="";31         //獲取XmlPullParser實(shí)例32         XmlPullParserFactory factory = XmlPullParserFactory.newInstance();33         XmlPullParser parser = factory.newPullParser();34         parser.setInput(inputStream, encode);35         //獲取解析事件36         int eventType = parser.getEventType();37         //當(dāng)xml文檔未到尾端時(shí)38         while (eventType != XmlPullParser.END_DOCUMENT) {39             switch (eventType) {40                 //解析根標(biāo)簽的時(shí)候,實(shí)例化集合41                 case XmlPullParser.START_DOCUMENT:42                     break;43                 case XmlPullParser.START_TAG:44                     if("string".equals(parser.getName())){45                         parser.next();46                         info=parser.getText();47                     }48                     break;49             }50             eventType = parser.next();51         }52         return info;53 54     }55 56 }

  關(guān)于博文詳情頁(yè)的實(shí)現(xiàn),我做了很多方法的嘗試,因?yàn)槲覀儷@取的數(shù)據(jù)是Html代碼,我們很自然的會(huì)想到用WebView,但是用WebView來(lái)展示,我們需要一個(gè)固定的樣式來(lái)控制頁(yè)面內(nèi)容,不然會(huì)導(dǎo)致頁(yè)面格式無(wú)法控制,比如文字的排布換行,圖片的大小控制,包括整體頁(yè)面的屏幕適配,由于我們獲取的只是部分Html代碼,所以會(huì)純?cè)诤芏鄦?wèn)題,并且有滑動(dòng)卡頓(對(duì)于安卓來(lái)說(shuō),WebView本來(lái)就是個(gè)軟肋)。

  然后我嘗試著用Html類(lèi)下的fromHtml方法來(lái)實(shí)現(xiàn)對(duì)頁(yè)面代碼的格式化,它是基于TextView的,發(fā)現(xiàn)滑動(dòng)很流暢,文字大小也可以控制的很好,但又有一個(gè)問(wèn)題出現(xiàn)了,關(guān)于圖片的展示問(wèn)題,雖然fromHtml提供了另外一個(gè)包含ImageGetter的構(gòu)造方法,但是在我們通過(guò)異步獲取圖片的時(shí)候它不發(fā)預(yù)知圖片尺寸的大小,導(dǎo)致最后獲取出來(lái)的圖片會(huì)覆蓋了文字。

效果如圖:

  后來(lái)我嘗試的去GitHub上找找開(kāi)源的組件發(fā)現(xiàn)了HtmlTextView:https://github.com/sufficientlysecure/html-textview,但是也不能夠達(dá)到想要的效果,最后無(wú)奈的用了一個(gè)最笨的方法去做,就是在我們獲取到Html格式數(shù)據(jù)的時(shí)候,我們通過(guò)String的replace方法用正則表達(dá)式方式去判斷位置,比如<img/>標(biāo)簽,然后通過(guò)添加換行符號(hào)<br/>來(lái)人工換行,這樣子看似沒(méi)什么問(wèn)題,但是圖片畢竟有很多,有大有小,也并不是很完美的可以解決問(wèn)題。

  最后我覺(jué)得不應(yīng)該老在安卓端里去考慮問(wèn)題,畢竟我們的數(shù)據(jù)是從網(wǎng)絡(luò)獲取下來(lái)的,我們對(duì)它們具有完全的掌控權(quán),為啥不從Html代碼端去考慮問(wèn)題的解決呢?然后我決定寫(xiě)一個(gè)靜態(tài)的Html模板,對(duì)它做了移動(dòng)端的屏幕適配,然后再把我們獲取到的內(nèi)容插入進(jìn)去。(這里而外再提一個(gè)方法,我們也可以通過(guò)Jsoup去解析Html代碼,然后去創(chuàng)建一個(gè)實(shí)體對(duì)象,把內(nèi)容加入到List集合,然后再通過(guò)頁(yè)面展示)

  好了,看下我的Html靜態(tài)模板的實(shí)現(xiàn):

這是Html模板:

 1 <html> 2 <head> 3     <title>Blog Content</title> 4     <meta name="viewport" 5           content="width=device-width, minimum-scale=0.5, initial-scale=1.2, maximum-scale=2.0, user-scalable=1"/> 6     <link rel="stylesheet" type="text/CSS" href="css.css"/> 7  8 </head> 9 <body>10 <div id="header">11     <h3>12         #title#13     </h3>14 15     <div class="describe"><p/>#author#<p/>16 17         <div id="info">#info#<p/>#time#</div>18     </div>19 </div>20 <div id="content">21     #content#22 </div>23 </body>24 </html>
BlogContent.html

這是Css文件:

 1 body{font-family:Helvetica,"Microsoft Yahei",Verdana,Helvetica,SimSun,Arial,"Arial Unicode MS",MingLiu,PMingLiu,"MS Gothic",sans-serief;margin:0;padding:0 8px;background-color:#efeff0;color:#333;Word-wrap:break-word;} 2 p{margin-top:0;margin-bottom:5pt;line-height: 1.6em;}   3 #header{text-align:center;background:transparent url('webBgLine.png') repeat-x scroll center bottom; padding-top:6pt;margin-bottom:5pt;-webkit-background-size:320px 2px;} 4 #header h3{margin-bottom:0px; margin-top:5px;font-size:14pt;padding:0 5pt;color:#464646;line-height:1.3em;} 5 .describe{color:#8e8e8e;font-size:12pt;padding:4pt 0; color:#333;} 6 #info{ font-size:10pt;line-height:1.6; color:#787878;} 7 #content{ font-size:12pt;line-height:1.8;} 8 img{max-width:80%;height:auto;} 9 div.bimg{text-align:center;padding:0;}10 .photo_title{font-weight:bold;font-size:14pt;margin-top:15px;}11 .langs_cn{color:#006200;}12 audio{width:100%}13 *{-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */14     /*-webkit-text-size-adjust: none;*/ /* prevent webkit from resizing text to fit */15     -webkit-tap-highlight-color: rgba(0,0,0,0.15); /* make transparent link selection, adjust last value opacity 0 to 1.0 */16     /*-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */17 }18 @media screen and (-webkit-device-pixel-ratio: 2) {19     #header{background-image:transparent url('webBgLine@2x.png') repeat-x scroll center bottom;-webkit-background-size:320px 1px;}20 }
Css.css

  這樣我們就可以通過(guò)Java端實(shí)現(xiàn)動(dòng)態(tài)插入了,由于是加載了靜態(tài)模板,滑動(dòng)起來(lái)也不會(huì)出現(xiàn)卡頓。

1 InputStream inputStream = getAssets().open("NewsDetail.html");2                     byte[] temp = AppUtil.readInputStream(inputStream);3                     String content = new String(temp);4                     mWebView.loadDataWithBaseURL("file:///android_asset/", content.replace("#title#", mBlog.getBlogTitle()).replace("#author#", "作者:" + mBlog.getAuthorName()).replace("#info#", "推薦:" + mBlog.getBlogDiggs() + "/t/t評(píng)論:" + mBlog.getBlogComments() + "/t/t瀏覽:" + mBlog.getBlogViews()).replace("#time#", TimeUtil.ParseDateToString(TimeUtil.ParseUTCDate(mBlog.getBlogPublished())))5                             .replace("#content#", mInfo), "text/html", "utf-8", null);

  看下布局文件,這里用到了一個(gè)Material Design里的FAB(Floating Action Button)浮動(dòng)按鈕,這個(gè)控件很簡(jiǎn)單,只需要設(shè)置對(duì)應(yīng)的屬性,然后其他用法和普通控件是保持一致的。

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:app="http://schemas.android.com/apk/res-auto" 3     android:layout_width="match_parent" 4     android:layout_height="match_parent" 5     android:fitsSystemWindows="true" 6     android:orientation="vertical"> 7  8     <!--ToolBar--> 9     <include layout="@layout/activity_toolbar" />10 11 12     <FrameLayout13         android:layout_width="match_parent"14         android:layout_height="match_parent">15 16         <WebView17             android:id="@+id/wv_blog_content"18             android:layout_width="match_parent"19             android:layout_height="match_parent"20             android:scrollbars="vertical"21             />22 23         <ProgressBar24             android:id="@+id/pb_bar"25             style="@style/MyProgressBar"26             android:layout_width="match_parent"27             android:layout_height="wrap_content"28             android:layout_gravity="center_vertical"29             android:indeterminate="true" />30 31         <android.support.design.widget.FloatingActionButton32             android:id="@+id/fab_comment"33             android:layout_width="wrap_content"34             android:layout_height="wrap_content"35             android:layout_gravity="right|bottom"36             android:layout_marginBottom="30dp"37             android:layout_marginRight="20dp"38             android:src="@mBlogContent.xml

  這里只是先簡(jiǎn)單的一個(gè)圖片替換和Toast的顯示,具體操作等下篇文章我們用到數(shù)據(jù)庫(kù)的時(shí)候再說(shuō)。

 1         mFloatingActionButton = (FloatingActionButton) findViewById(R.id.fab_comment); 2  3         mFloatingActionButton.setOnClickListener(new View.OnClickListener() { 4             @Override 5             public void onClick(View v) { 6                 if (!isLike) { 7                     isLike = true; 8                     mFloatingActionButton.setImageResource(R.mipmap.ic_grade_white_24dp); 9                     Toast.makeText(BlogContentActivity.this, "文章已收藏", Toast.LENGTH_SHORT).show();10                     //添加收藏文章到數(shù)據(jù)庫(kù)11                 } else {12                     isLike = false;13                     mFloatingActionButton.setImageResource(R.mipmap.ic_star_outline_white_24dp);14                     Toast.makeText(BlogContentActivity.this, "取消文章收藏", Toast.LENGTH_SHORT).show();15                     //從數(shù)據(jù)庫(kù)刪除收藏文章16                 }17             }18         });

  然后這里是關(guān)于WebView的設(shè)置,大家也可以參考這篇文章自己做設(shè)置:http://www.pedant.cn/2014/09/10/webview-optimize-points/#0-tsina-1-5518-397232819ff9a47a7b7e80a40613cfe1

 1 mWebView = (WebView) findViewById(R.id.wv_blog_content); 2         //避免中文亂碼 3         mWebView.getSettings().setDefaultTextEncodingName("utf-8"); 4         //適配低版本,關(guān)閉圖片自動(dòng)加載 5         if (Build.VERSION.SDK_INT >= 19) { 6             mWebView.getSettings().setLoadsImagesAutomatically(true); 7         } else { 8             mWebView.getSettings().setLoadsImagesAutomatically(false); 9         }10         //等頁(yè)面加載完畢再加載圖片11         WebViewClient webViewClient = new WebViewClient() {12             @Override13             public void onPageFinished(WebView view, String url) {14                 //關(guān)閉Progress15                 mProgressBar.setVisibility(View.GONE);16                 if (!view.getSettings().getLoadsImagesAutomatically()) {17                     view.getSettings().setLoadsImagesAutomatically(true);18                 }19             }20         };21         mWebView.setWebViewClient(webViewClient);22         mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);23         mWebView.getSettings().setJavascriptEnabled(false);24         mWebView.getSettings().setSupportZoom(false);25         mWebView.getSettings().setBuiltInZoomControls(false);26         mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);27         mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);

3、關(guān)于評(píng)論詳情頁(yè)面的實(shí)現(xiàn)

  這里是關(guān)于博文詳情的接口:http://wcf.open.VEVb.com/blog/post/{POSTID}/comments/{PAGEINDEX}/{PAGESIZE}(POSTID代表文章Id,PAGEINDEX代表評(píng)論頁(yè)數(shù),PAGESIZE代表評(píng)論每頁(yè)展示的條數(shù))這里不得不吐槽下接口的殘疾,都沒(méi)提供用戶(hù)頭像數(shù)據(jù),只能用默認(rèn)灰白頭像做了。

  這個(gè)就很簡(jiǎn)單了,直接可以復(fù)制我們之前做首頁(yè)列表的XML布局文件甚至是Fragment里的主邏輯代碼,只需要做一下頁(yè)面內(nèi)容的小改動(dòng)就可以了,下面直接給代碼。

博文評(píng)論主頁(yè)樣式:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:app="http://schemas.android.com/apk/res-auto" 3     android:layout_width="match_parent" 4     android:layout_height="match_parent" 5     android:fitsSystemWindows="true" 6     android:gravity="center" 7     android:orientation="vertical"> 8  9     <!--ToolBar-->10     <include layout="@layout/activity_toolbar" />11     <android.support.v4.widget.SwipeRefreshLayout12         android:id="@+id/swipe_refresh"13         android:layout_width="match_parent"14         android:layout_height="match_parent"15         android:layout_margin="4dp">16 17         <android.support.v7.widget.RecyclerView18             android:id="@+id/rv_view"19             android:layout_width="match_parent"20             android:layout_height="match_parent"21             android:background="@color/md_grey_200"22             android:scrollbars="vertical"23             />24     </android.support.v4.widget.SwipeRefreshLayout>25 26     <com.lcw.rabbit.myblog.view.MyProgressBar27         android:id="@+id/progressbar"28         android:layout_width="match_parent"29         android:layout_height="20dp"30         android:layout_gravity="bottom"31         android:visibility="gone"32         />33 34 35 36 </LinearLayout>
activity_blog_comment.xml

列表樣式和詳細(xì)內(nèi)容樣式:

 1 <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:app="http://schemas.android.com/apk/res-auto" 3     android:id="@+id/cv_cardview" 4     android:layout_width="match_parent" 5     android:layout_height="wrap_content" 6     android:layout_margin="8dp" 7     android:gravity="center" 8     app:cardCornerRadius="6dp"> 9 10     <include layout="@layout/recyclerview_item_blogcommentlist_content" />11 12 </android.support.v7.widget.CardView>
recyclerview_blogcommentlist.xml
 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:app="http://schemas.android.com/apk/res-auto" 3     android:layout_width="match_parent" 4     android:layout_height="wrap_content" 5     android:background="?android:selectableItemBackground" 6     android:orientation="horizontal" 7     android:padding="3dp"> 8  9     <!--信息內(nèi)容-->10     <LinearLayout11         android:layout_width="0dp"12         android:layout_height="wrap_content"13         android:layout_marginLeft="3dp"14         android:layout_weight="1"15         android:orientation="vertical">16 17         <LinearLayout18             android:layout_width="wrap_content"19             android:layout_height="wrap_content"20             android:layout_marginLeft="3dp"21             android:layout_weight="1"22             android:padding="3dp"23             android:orientation="horizontal">24 25             <!--頭像-->26             <com.makeramen.roundedimageview.RoundedImageView27                 android:id="@+id/iv_userhead"28                 android:layout_width="25dp"29                 android:layout_height="25dp"30                 android:layout_gravity="center_vertical"31                 android:layout_marginRight="5dp"32                 android:src="@mipmap/avatar_default"33                 app:riv_border_color="#ffffff"34                 app:riv_border_width="2dip"35                 app:riv_corner_radius="30dip"36                 app:riv_mutate_background="true"37                 app:riv_oval="true"38                 app:riv_tile_mode="repeat" />39 40             <TextView41                 android:id="@+id/tv_name"42                 android:layout_width="match_parent"43                 android:layout_height="wrap_content"44                 android:layout_gravity="center_vertical"45                 android:layout_marginTop="2dp"46                 android:layout_weight="1"47                 android:ellipsize="end"48                 android:singleLine="true"49 50                 android:text="用戶(hù)昵稱(chēng)"51                 android:textColor="@color/md_green_700"52                 android:textSize="16sp"53                 android:textStyle="bold" />54         </LinearLayout>55 56         <TextView57             android:id="@+id/tv_comment"58             android:layout_width="match_parent"59             android:layout_height="wrap_content"60             android:layout_weight="1"61             android:maxLines="3"62             android:layout_marginLeft="3dp"63             android:text="文章評(píng)論內(nèi)容"64             android:textSize="16sp" />65 66         <LinearLayout67             android:layout_width="match_parent"68             android:layout_height="match_parent"69             android:layout_margin="1dp"70             android:layout_weight="1"71             android:padding="3dp"72             android:orientation="horizontal">73 74             <TextView75                 android:layout_width="wrap_content"76                 android:layout_height="match_parent"77                 android:gravity="center_vertical"78                 android:text="評(píng)論時(shí)間:"79                 android:textColor="@color/md_grey_500"80                 android:textSize="12sp" />81 82             <TextView83                 android:id="@+id/tv_time"84                 android:layout_width="wrap_content"85                 android:layout_height="match_parent"86                 android:layout_marginRight="5dp"87                 android:gravity="center_vertical"88                 android:textColor="@color/md_grey_500"89                 android:textSize="12sp" />90 91         </LinearLayout>92 93     </LinearLayout>94 95 96 </LinearLayout>
recyclerview_blogcommentlist_content.xml

主代碼:

  1 package com.lcw.rabbit.myblog;  2   3 import android.os.Bundle;  4 import android.support.v4.widget.SwipeRefreshLayout;  5 import android.support.v7.app.AppCompatActivity;  6 import android.support.v7.widget.DefaultItemAnimator;  7 import android.support.v7.widget.LinearLayoutManager;  8 import android.support.v7.widget.RecyclerView;  9 import android.support.v7.widget.Toolbar; 10 import android.view.View; 11  12 import com.android.volley.Request; 13 import com.android.volley.Response; 14 import com.android.volley.VolleyError; 15 import com.android.volley.toolbox.StringRequest; 16 import com.lcw.rabbit.myblog.adapter.BlogCommentListAdapter; 17 import com.lcw.rabbit.myblog.entity.Comment; 18 import com.lcw.rabbit.myblog.parser.BlogCommentXmlParser; 19 import com.lcw.rabbit.myblog.utils.VolleyRequestQueueManager; 20 import com.lcw.rabbit.myblog.view.MyProgressBar; 21 import com.mugen.Mugen; 22 import com.mugen.MugenCallbacks; 23 import com.mugen.attachers.BaseAttacher; 24  25 import org.xmlpull.v1.XmlPullParserException; 26  27 import java.io.ByteArrayInputStream; 28 import java.io.IOException; 29 import java.util.ArrayList; 30 import java.util.List; 31  32 /** 33  * 博文評(píng)論頁(yè) 34  */ 35 public class BlogCommentActivity extends AppCompatActivity { 36     private Toolbar mToolbar; 37     private SwipeRefreshLayout mSwipeRefreshLayout; 38     private RecyclerView mRecyclerView; 39     private BlogCommentListAdapter mBlogCommentListAdapter; 40     //無(wú)限滾動(dòng) 41     private BaseAttacher mBaseAttacher; 42     private MyProgressBar myProgressBar; 43  44     private String mBlogId; 45     private List<Comment> mComments; 46  47     //默認(rèn)第一頁(yè) 48     private int currentPage = 1; 49     //是否正在加載 50     private boolean isLoading = false; 51  52  53     @Override 54     protected void onCreate(Bundle savedInstanceState) { 55         super.onCreate(savedInstanceState); 56         setContentView(R.layout.activity_blog_comment); 57         initView(); 58         initData(); 59         initAction(); 60         getBlogComment(mBlogId, 1, 10); 61     } 62  63     private void initAction() { 64         //設(shè)置下拉刷新 65         mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 66             @Override 67             public void onRefresh() { 68                 getBlogComment(mBlogId, 1, 10); 69             } 70         }); 71  72  73         //設(shè)置無(wú)限滾動(dòng),上拉加載 74         mBaseAttacher = Mugen.with(mRecyclerView, new MugenCallbacks() { 75             @Override 76             public void onLoadMore() { 77                 //加載更多 78                 isLoading = true; 79                 mBaseAttacher.setLoadMoreEnabled(false); 80                 myProgressBar.setVisibility(View.VISIBLE); 81                 getBlogComment(mBlogId, (currentPage + 1), 10); 82             } 83  84             @Override 85             public boolean isLoading() { 86                 return isLoading; 87             } 88  89             @Override 90             public boolean hasLoadedAllItems() { 91                 return isLoading; 92             } 93         }).start(); 94         //離底部一項(xiàng)的時(shí)候加載更多 95         mBaseAttacher.setLoadMoreOffset(1); 96     } 97  98     /** 99      * 獲取Intent傳遞過(guò)來(lái)的數(shù)據(jù)100      */101     private void initData() {102         mBlogId = getIntent().getExtras().getString("blogId");103         //設(shè)置空數(shù)據(jù)源104         mComments=new ArrayList<Comment>();105         mBlogCommentListAdapter = new BlogCommentListAdapter(this,mComments);106         mRecyclerView.setAdapter(mBlogCommentListAdapter);107     }108 109 110     /**111      * 獲取博客評(píng)論數(shù)據(jù)并設(shè)置112      * @param blogId113      * @param page114      * @param num115      */116     private void getBlogComment(String blogId, final int page, int num) {117         //更新當(dāng)前頁(yè)數(shù)118         currentPage = page;119         StringRequest request = new StringRequest(Request.Method.GET, "http://wcf.open.VEVb.com/blog/post/" + blogId + "/comments/" + page + "/" + num, new Response.Listener<String>() {120             @Override121             public void onResponse(String s) {122                 try {123                     //獲取評(píng)論數(shù)據(jù)數(shù)據(jù)并解析XML124                     ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());125                     List<Comment> comments = BlogCommentXmlParser.getBlogComment(inputStream, "utf-8");126                     if (page == 1) {127                         //清空之前的數(shù)據(jù)預(yù)防重復(fù)加載128                         mComments.clear();129                     }130                     for (Comment comment : comments) {131                         //整理數(shù)據(jù)源132                         mComments.add(comment);133                     }134 135                     if (mBlogCommentListAdapter == null) {136                         //如果Adapter不存在137                         mBlogCommentListAdapter = new BlogCommentListAdapter(BlogCommentActivity.this,mComments);138                         mRecyclerView.setAdapter(mBlogCommentListAdapter);139                     } else {140                         //存在通知adatper數(shù)據(jù)源更新141                         mBlogCommentListAdapter.refreshData(mComments);142 143                     }144                     //關(guān)閉下拉刷新樣式145                     mSwipeRefreshLayout.setRefreshing(false);146                     isLoading = false;147                     myProgressBar.setVisibility(View.GONE);148                     mBaseAttacher.setLoadMoreEnabled(true);149 150 151                 } catch (XmlPullParserException e) {152                     e.printStackTrace();153                 } catch (IOException e) {154                     e.printStackTrace();155                 }156             }157         }, new Response.ErrorListener() {158             @Override159             public void onErrorResponse(VolleyError volleyError) {160 161             }162         });163         VolleyRequestQueueManager.addRequest(request, "BlogCommentList");164 165     }166 167     private void initView() {168         mToolbar = (Toolbar) findViewById(R.id.activity_toolbar);169         mToolbar.setTitle("文章評(píng)論");170         setSupportActionBar(mToolbar);171         getSupportActionBar().setDisplayHomeAsUpEnabled(true);172 173         mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);174         //設(shè)置拉下刷新滾動(dòng)條顏色175         mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light, android.R.color.holo_orange_light, android.R.color.holo_green_light);176         mRecyclerView = (RecyclerView) findViewById(R.id.rv_view);177         mRecyclerView.setLayoutManager(new LinearLayoutManager(this));178         mRecyclerView.setItemAnimator(new DefaultItemAnimator());179         myProgressBar = (MyProgressBar)findViewById(R.id.progressbar);180 181 182     }183 184 185 }

適配器代碼:

  1 package com.lcw.rabbit.myblog.adapter;  2   3 import android.content.Context;  4 import android.content.res.Resources;  5 import android.graphics.Bitmap;  6 import android.graphics.BitmapFactory;  7 import android.support.v7.widget.RecyclerView;  8 import android.text.Html;  9 import android.view.LayoutInflater; 10 import android.view.View; 11 import android.view.ViewGroup; 12 import android.widget.TextView; 13  14 import com.lcw.rabbit.myblog.R; 15 import com.lcw.rabbit.myblog.entity.Comment; 16 import com.lcw.rabbit.myblog.utils.TimeUtil; 17 import com.makeramen.roundedimageview.RoundedImageView; 18  19 import java.util.List; 20  21 /** 22  * 推薦博文評(píng)論列表適配器 23  * Created by Lichenwei 24  * Date: 2015-08-16 25  * Time: 22:34 26  */ 27 public class BlogCommentListAdapter extends RecyclerView.Adapter<BlogCommentListAdapter.RecyclerViewViewHolder> { 28  29     private Context mContext; 30     private List<Comment> mComments; 31  32     public BlogCommentListAdapter(Context context, List<Comment> comments) { 33         this.mContext = context; 34         this.mComments = comments; 35     } 36  37     /** 38      * 設(shè)置新的數(shù)據(jù)源,提醒a(bǔ)datper更新 39      * 40      * @param comments 41      */ 42     public void refreshData(List<Comment> comments) { 43         this.mComments = comments; 44         this.notifyDataSetChanged(); 45     } 46  47     /** 48      * 創(chuàng)建ViewHolder 49      * 50      * @param viewGroup 51      * @param i 52      * @return 53      */ 54     @Override 55     public RecyclerViewViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 56         View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_item_blogcommentlist, viewGroup, false); 57         return new RecyclerViewViewHolder(view); 58     } 59  60     /** 61      * 根據(jù)資源ID返回Bitmap對(duì)象 62      * 63      * @param resId 64      * @return 65      */ 66     public Bitmap getBitmapFromRes(int resId) { 67         Resources res = mContext.getResources(); 68         return BitmapFactory.decodeResource(res, resId); 69  70     } 71  72     /** 73      * 綁定數(shù)據(jù) 74      * 75      * @param viewholder 76      * @param i 77      */ 78     @Override 79     public void onBindViewHolder(RecyclerViewViewHolder viewholder, int i) { 80         //設(shè)置頭像 81 //        if (mAuthors.get(i).getAuthorPic() != null && !"".equals(mAuthors.get(i).getAuthorPic())) { 82 //            ImageCacheManager.loadImage(mAuthors.get(i).getAuthorPic(), viewholder.mUserhead, getBitmapFromRes(R.mipmap.avatar_default), getBitmapFromRes(R.mipmap.avatar_default)); 83 //        } else { 84 //            viewholder.mUserhead.setImageResource(R.mipmap.avatar_default); 85 //        } 86         viewholder.mName.setText(mComments.get(i).getAuthorName()); 87         //處理評(píng)論內(nèi)容里的Html代碼 88         viewholder.mContent.setText(Html.fromHtml(mComments.get(i).getCommentContent())); 89         //處理日期特殊格式 90         viewholder.mTime.setText(TimeUtil.DateToChineseString(TimeUtil.ParseUTCDate(mComments.get(i).getCommentTime()))); 91     } 92  93     @Override 94     public int getItemCount() { 95         return mComments.size(); 96     } 97  98     /** 99      * 自定義ViewHolder100      */101     public static class RecyclerViewViewHolder extends RecyclerView.ViewHolder {102         private RoundedImageView mUserhead;103         private TextView mName;104         private TextView mContent;105         private TextView mTime;106 107         public RecyclerViewViewHolder(View view) {108             super(view);109             mUserhead = (RoundedImageView) view.findViewById(R.id.iv_userhead);110             mName = (TextView) view.findViewById(R.id.tv_name);111             mContent = (TextView) view.findViewById(R.id.tv_comment);112             mTime = (TextView) view.findViewById(R.id.tv_time);113 114         }115 116 117     }118 }

獲取博文詳情XML解析:

 1 package com.lcw.rabbit.myblog.parser; 2  3 import com.lcw.rabbit.myblog.entity.Comment; 4  5 import org.xmlpull.v1.XmlPullParser; 6 import org.xmlpull.v1.XmlPullParserException; 7 import org.xmlpull.v1.XmlPullParserFactory; 8  9 import java.io.IOException;10 import java.io.InputStream;11 import java.util.ArrayList;12 import java.util
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 兴安盟| 社旗县| 青铜峡市| 南安市| 赫章县| 嫩江县| 灵宝市| 烟台市| 吉安市| 呼和浩特市| 仁化县| 全椒县| 瑞丽市| 宁陵县| 林芝县| 太湖县| 怀集县| 南城县| 南昌县| 徐州市| 望奎县| 峨山| 泌阳县| 威远县| 高安市| 全椒县| 旅游| 塔城市| 锡林郭勒盟| 梅州市| 宝应县| 富阳市| 九寨沟县| 潼关县| 惠东县| 中山市| 华宁县| 虞城县| 丽江市| 南雄市| 皋兰县|