亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

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

2019-11-15 01:15:10
字體:
來源:轉載
供稿:網友
安卓開發筆記——打造屬于自己的博客園APP(三)

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

  今天來講講博客詳情頁和評論頁面的實現,國際慣例,先上效果圖:(動態圖片比較大,加載需要點時間)

 

  這里說下,關于上篇文章xml的解析,我后來查了下確實有一些方便解析的工具,例如:FastXML,Xstram等且效率更高,這里是在它的官方找到的一張數據圖:

文章里我就還是先采用原生的pull解析了,等重構代碼時候再換上工具類吧,先把項目做完。 

  好了,廢話不多說了,直接進入主題:

1、關于RecyclerView的點擊事件

  首先先來說下關于RecyclerView的點擊監聽事件,在上篇文章提到,RecyclerView是ListView升級版,顧名思義它是為效率而生的,它不關心多余的任何事情,比如Item項的動作監聽,Item項的分割線,Item項的添加動畫效果,只專注于數據的展示實現,相比ListView它更符合軟件設計原則,更加解耦。

  上面提到它不關心Item項的動作監聽,很自然,它沒有和ListView控件一樣提供類似setOnItemClickListener這種監聽方法,需要我們自己來實現,那么很自然的,我們會選擇在Adapter里去設置監聽事件,關于RecyclerView不熟悉的朋友可以先看下這篇文章:http://blog.csdn.net/lmj623565791/article/details/45059587

  首先我們在Adapter設置一個點擊回調接口,并提供setter方法:

 1     /** 2      * 自定義點擊回調接口 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     }

  然后我們在onBindViewHolder中設置監聽事件:

1         //設置點擊監聽2         viewholder.itemView.setTag(i);3         viewholder.mMore.setTag(Integer.MAX_VALUE);4         viewholder.itemView.setOnClickListener(new ItemClick());5         viewholder.mMore.setOnClickListener(new ItemClick());

  再來個實現接口:

    /**     * 點擊事件實現類     */    public class ItemClick implements View.OnClickListener{        @Override        public void onClick(View v) {            if(mRecyclerViewListener!=null){                mRecyclerViewListener.setOnclickListener(v,(int)v.getTag());            }        }    }

  這樣子,我們就可以在我們的博客列表頁面設置點擊事件了,關于下面的showPopUpMenu是一個點擊彈出窗口,可以實現收藏博文和關注博主的功能,我們下一篇文章會提到。這里我們實現當點擊RecyclerView條目的時候會通過Intent傳遞Blog對象到博文詳情頁面。

 1         //設置條目點擊監聽 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                     //點擊菜單按鈕 8                     showPopUpMenu(view, pos); 9                 } else {10                     //點擊條目,傳遞對象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、關于博文詳情頁面的實現

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

這里是關于博文詳情的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  * 對博文詳情xml數據的解析12  * Created by Lichenwei13  * Date: 2015-08-1714  * Time: 13:3215  */16 public class BlogContentXmlParser {17 18 19     /**20      * 用于解析博文詳情的xml,返回Avatar的List集合對象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實例32         XmlPullParserFactory factory = XmlPullParserFactory.newInstance();33         XmlPullParser parser = factory.newPullParser();34         parser.setInput(inputStream, encode);35         //獲取解析事件36         int eventType = parser.getEventType();37         //當xml文檔未到尾端時38         while (eventType != XmlPullParser.END_DOCUMENT) {39             switch (eventType) {40                 //解析根標簽的時候,實例化集合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 }

  關于博文詳情頁的實現,我做了很多方法的嘗試,因為我們獲取的數據是Html代碼,我們很自然的會想到用WebView,但是用WebView來展示,我們需要一個固定的樣式來控制頁面內容,不然會導致頁面格式無法控制,比如文字的排布換行,圖片的大小控制,包括整體頁面的屏幕適配,由于我們獲取的只是部分Html代碼,所以會純在很多問題,并且有滑動卡頓(對于安卓來說,WebView本來就是個軟肋)。

  然后我嘗試著用Html類下的fromHtml方法來實現對頁面代碼的格式化,它是基于TextView的,發現滑動很流暢,文字大小也可以控制的很好,但又有一個問題出現了,關于圖片的展示問題,雖然fromHtml提供了另外一個包含ImageGetter的構造方法,但是在我們通過異步獲取圖片的時候它不發預知圖片尺寸的大小,導致最后獲取出來的圖片會覆蓋了文字。

效果如圖:

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

  最后我覺得不應該老在安卓端里去考慮問題,畢竟我們的數據是從網絡獲取下來的,我們對它們具有完全的掌控權,為啥不從Html代碼端去考慮問題的解決呢?然后我決定寫一個靜態的Html模板,對它做了移動端的屏幕適配,然后再把我們獲取到的內容插入進去。(這里而外再提一個方法,我們也可以通過Jsoup去解析Html代碼,然后去創建一個實體對象,把內容加入到List集合,然后再通過頁面展示)

  好了,看下我的Html靜態模板的實現:

這是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

  這樣我們就可以通過Java端實現動態插入了,由于是加載了靜態模板,滑動起來也不會出現卡頓。

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評論:" + mBlog.getBlogComments() + "/t/t瀏覽:" + mBlog.getBlogViews()).replace("#time#", TimeUtil.ParseDateToString(TimeUtil.ParseUTCDate(mBlog.getBlogPublished())))5                             .replace("#content#", mInfo), "text/html", "utf-8", null);

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

 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

  這里只是先簡單的一個圖片替換和Toast的顯示,具體操作等下篇文章我們用到數據庫的時候再說。

 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                     //添加收藏文章到數據庫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                     //從數據庫刪除收藏文章16                 }17             }18         });

  然后這里是關于WebView的設置,大家也可以參考這篇文章自己做設置: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         //適配低版本,關閉圖片自動加載 5         if (Build.VERSION.SDK_INT >= 19) { 6             mWebView.getSettings().setLoadsImagesAutomatically(true); 7         } else { 8             mWebView.getSettings().setLoadsImagesAutomatically(false); 9         }10         //等頁面加載完畢再加載圖片11         WebViewClient webViewClient = new WebViewClient() {12             @Override13             public void onPageFinished(WebView view, String url) {14                 //關閉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、關于評論詳情頁面的實現

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

  這個就很簡單了,直接可以復制我們之前做首頁列表的XML布局文件甚至是Fragment里的主邏輯代碼,只需要做一下頁面內容的小改動就可以了,下面直接給代碼。

博文評論主頁樣式:

 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

列表樣式和詳細內容樣式:

 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     <!--信息內容-->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="用戶昵稱"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="文章評論內容"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="評論時間:"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  * 博文評論頁 34  */ 35 public class BlogCommentActivity extends AppCompatActivity { 36     private Toolbar mToolbar; 37     private SwipeRefreshLayout mSwipeRefreshLayout; 38     private RecyclerView mRecyclerView; 39     private BlogCommentListAdapter mBlogCommentListAdapter; 40     //無限滾動 41     private BaseAttacher mBaseAttacher; 42     private MyProgressBar myProgressBar; 43  44     private String mBlogId; 45     private List<Comment> mComments; 46  47     //默認第一頁 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         //設置下拉刷新 65         mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 66             @Override 67             public void onRefresh() { 68                 getBlogComment(mBlogId, 1, 10); 69             } 70         }); 71  72  73         //設置無限滾動,上拉加載 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         //離底部一項的時候加載更多 95         mBaseAttacher.setLoadMoreOffset(1); 96     } 97  98     /** 99      * 獲取Intent傳遞過來的數據100      */101     private void initData() {102         mBlogId = getIntent().getExtras().getString("blogId");103         //設置空數據源104         mComments=new ArrayList<Comment>();105         mBlogCommentListAdapter = new BlogCommentListAdapter(this,mComments);106         mRecyclerView.setAdapter(mBlogCommentListAdapter);107     }108 109 110     /**111      * 獲取博客評論數據并設置112      * @param blogId113      * @param page114      * @param num115      */116     private void getBlogComment(String blogId, final int page, int num) {117         //更新當前頁數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                     //獲取評論數據數據并解析XML124                     ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());125                     List<Comment> comments = BlogCommentXmlParser.getBlogComment(inputStream, "utf-8");126                     if (page == 1) {127                         //清空之前的數據預防重復加載128                         mComments.clear();129                     }130                     for (Comment comment : comments) {131                         //整理數據源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數據源更新141                         mBlogCommentListAdapter.refreshData(mComments);142 143                     }144                     //關閉下拉刷新樣式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("文章評論");170         setSupportActionBar(mToolbar);171         getSupportActionBar().setDisplayHomeAsUpEnabled(true);172 173         mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);174         //設置拉下刷新滾動條顏色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  * 推薦博文評論列表適配器 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      * 設置新的數據源,提醒adatper更新 39      * 40      * @param comments 41      */ 42     public void refreshData(List<Comment> comments) { 43         this.mComments = comments; 44         this.notifyDataSetChanged(); 45     } 46  47     /** 48      * 創建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      * 根據資源ID返回Bitmap對象 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      * 綁定數據 74      * 75      * @param viewholder 76      * @param i 77      */ 78     @Override 79     public void onBindViewHolder(RecyclerViewViewHolder viewholder, int i) { 80         //設置頭像 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         //處理評論內容里的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
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
92看片淫黄大片看国产片| 国产精品视频不卡| 最近更新的2019中文字幕| 亚洲剧情一区二区| 国产成人精彩在线视频九色| 亚洲欧美日本另类| 这里只有精品丝袜| 国产精品久久久久久av| 亚洲欧美一区二区三区四区| 久久久91精品国产| 亚洲国产天堂久久综合网| 国产999精品久久久影片官网| 国产玖玖精品视频| 欧美日韩一区免费| 精品网站999www| 精品人伦一区二区三区蜜桃网站| 欧美日韩美女在线| 2019亚洲日韩新视频| 久久久久北条麻妃免费看| 国产一区二区三区久久精品| 黑人巨大精品欧美一区二区免费| 日韩av片免费在线观看| 亚洲欧美精品suv| 国产精品久久久久久av| 91久久精品一区| 亚洲小视频在线| 欧美视频在线视频| 欧美日韩视频在线| 亚洲欧美一区二区精品久久久| 在线成人激情视频| 国产精品久久久久久超碰| 中文字幕日韩精品有码视频| 国自在线精品视频| 日韩欧美一区二区三区| 色哟哟网站入口亚洲精品| 色爱av美腿丝袜综合粉嫩av| 成人久久久久爱| 国产精品91一区| 日韩精品福利网站| 91精品久久久久久久久久另类| 欧美自拍视频在线观看| 国产亚洲aⅴaaaaaa毛片| 欧美主播福利视频| 国产色婷婷国产综合在线理论片a| 久久九九免费视频| 热re99久久精品国产66热| 国产精品网站大全| 日韩精品www| 日韩高清电影好看的电视剧电影| 午夜精品福利在线观看| 欧美性猛交xxxx富婆弯腰| 91系列在线播放| 亚洲电影免费观看高清完整版在线观看| 久久成人人人人精品欧| 久久艳片www.17c.com| 色狠狠av一区二区三区香蕉蜜桃| 国产日本欧美一区| 黄色一区二区在线观看| 国内伊人久久久久久网站视频| 91精品成人久久| 精品福利樱桃av导航| 九九久久综合网站| 亚洲精品欧美日韩| www日韩中文字幕在线看| 久久久久五月天| 久久精品精品电影网| 日韩av免费在线看| 成人激情视频在线播放| 免费av在线一区| 国产精品无码专区在线观看| 亚洲国产成人久久| 日韩av快播网址| 91经典在线视频| 亚洲综合国产精品| 国外成人性视频| 欧美极品少妇xxxxⅹ免费视频| 欧美乱大交xxxxx另类电影| 久久av中文字幕| 亚洲最大激情中文字幕| 久久精品成人欧美大片古装| 久久久久久久久国产精品| 中文字幕欧美专区| 深夜成人在线观看| 国产精品自产拍高潮在线观看| 亚洲奶大毛多的老太婆| 亚洲美女福利视频网站| 日韩av在线免费播放| 伊人一区二区三区久久精品| 亚洲欧美一区二区三区情侣bbw| 亚洲va男人天堂| 欧美精品videosex性欧美| 欧洲亚洲免费视频| 国产欧美在线观看| 亚洲男人天堂2024| 久久成年人免费电影| 欧美夫妻性视频| 亚洲精品视频久久| 亚洲国产精品悠悠久久琪琪| 亚洲美女精品久久| 欧美日韩视频免费播放| 不卡av电影在线观看| 日韩成人在线电影网| 亚洲午夜国产成人av电影男同| 2019av中文字幕| 欧美高清视频免费观看| 国产精品扒开腿爽爽爽视频| 欧美激情中文网| 色阁综合伊人av| 高清欧美性猛交xxxx| 亚洲精品国产精品国自产在线| 91啪国产在线| 亚洲综合大片69999| 日韩在线观看网站| 久久精品99久久久香蕉| 亚洲精品av在线播放| 亚洲第一福利网站| 青青久久av北条麻妃黑人| 欧美日韩亚洲视频| 亚洲第一网站男人都懂| 欧美高清不卡在线| 久久99热精品这里久久精品| 国产丝袜一区视频在线观看| 国产精品嫩草影院久久久| 国产在线精品自拍| 中文字幕视频在线免费欧美日韩综合在线看| 国产视频精品va久久久久久| 久久人人爽人人爽人人片亚洲| 欧美极品第一页| 中文字幕亚洲一区二区三区| 黄色成人av在线| 98精品国产自产在线观看| 2019亚洲男人天堂| 欧美精品xxx| 国产一区二区三区高清在线观看| 成人春色激情网| 国产精品av在线播放| 日韩在线欧美在线国产在线| 久久久久久国产| 欧美激情精品久久久久久黑人| 亚洲国产第一页| 欧美在线视频免费| 亚洲男人的天堂在线| 亚洲欧美另类国产| 国产成人精品综合| 最近中文字幕mv在线一区二区三区四区| 亚洲精品永久免费| 91日本在线观看| 欧美疯狂做受xxxx高潮| 欧美午夜电影在线| 高清在线视频日韩欧美| 日韩女优在线播放| 精品无人区乱码1区2区3区在线| 日韩国产高清污视频在线观看| 日韩av电影手机在线观看| 国产精品免费电影| 在线免费观看羞羞视频一区二区| 亚洲乱码国产乱码精品精| 国产日韩在线观看av| 亚洲高清在线观看| 日韩小视频在线| www.日韩.com| 日韩精品中文字幕在线| 视频在线观看一区二区| 亚洲人成电影网站色|