本文出自:http://blog.csdn.net/dt235201314/article/details/79076963
一丶效果图
二丶实现功能
1.抓取个人CSDN博客主页(旧版 “http://blog.csdn.net/DT235201314”)数据
2.侧滑页面展示博主相关消息
3.fragment展现分类简要博文
4.WebView展示文章内容
三丶看代码
博主信息类(略 排名 头像 文章数等)
简要博文类(略 标题 摘要 时间 url等)
抓取数据工具类
JsoupUtil.java
Jsoup使用参考: jsoup使用之抓取CSDN个人博客内容
/** * 作者: 叶应是叶 * 时间: 2017/3/20 10:44 * 描述: 用来解析各项网页信息 */ public class JsoupUtil { /** * 博客网站首页 */ private static final String BASE_PATH = "http://blog.csdn.net/"; /** * 博主主页 */ private static final String BLOG_HOMEPAGE = BASE_PATH + Constants.BLOG_AUTHOR_NAME; /** * 获取博主的基本信息 * * @return 博主信息 */ public static BlogAuthor getBlogAutoMessage() { Document doc; BlogAuthor blogAuthor = null; Elements elements; /**作者名字*/ String authorName; /** 访问数量*/ String visitNumber; /** 积分*/ String mark; /** 排名*/ String rank; /** 原创文章数量*/ String originalArticleNumber; /** 转载文章数量*/ String reprintArticleNumber; /** 翻译文章数量*/ String translateArticleNumber; /** 评论数量*/ String commentNumber; /** 头像链接*/ String avatarUrl; /**我的代号*/ String code; /**我的名言*/ String myHelloWorld; try { doc = Jsoup.connect(BLOG_HOMEPAGE) .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31") //"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31" //"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0" .timeout(10000).get(); if (doc != null) { elements = doc.select("div#blog_title").select("h2").select("a"); code = elements.first().text(); elements = doc.select("div#blog_title").select("h3"); myHelloWorld = elements.first().text(); elements = doc.select("div#blog_userface").select("a.user_name"); authorName = elements.first().text(); elements = doc.select("div#blog_userface").select("a").select("img"); avatarUrl = elements.first().attr("src"); elements = doc.select("ul#blog_rank").select("li"); visitNumber = elements.get(0).text(); mark = elements.get(1).text(); rank = elements.get(3).text(); elements = doc.select("ul#blog_statistics").select("li"); originalArticleNumber = elements.get(0).text(); reprintArticleNumber = elements.get(1).text(); translateArticleNumber = elements.get(2).text(); commentNumber = elements.get(3).text(); blogAuthor = new BlogAuthor(code,myHelloWorld,authorName, visitNumber, mark, rank, originalArticleNumber, reprintArticleNumber, translateArticleNumber, commentNumber, avatarUrl); } } catch (Exception e) { e.printStackTrace(); blogAuthor = new BlogAuthor("行动者&&职业化","没有内心的平静就没有真正意义上的幸福","天一方蓝", "访问:0", "积分:0", "积分:0", "原创:0", "转载:0", "译文:0", "评论:0", ""); } return blogAuthor; } /** * 获取博主所有博客分类信息,包括分类目录,目录下文章数量,该分类的链接 * * @return 分类信息 */ private static List<BlogCategory> getBlogAllCategory() { Document doc; Elements elements = null; List<BlogCategory> blogCategoryList = null; BlogCategory blogCategory; try { doc = Jsoup.connect(BLOG_HOMEPAGE) .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31") .timeout(10000).get(); if (doc != null) { elements = doc.select("div#panel_Category").select("ul.panel_body > li"); } if (elements != null && !"".equals(elements.toString())) { blogCategoryList = new ArrayList<>(); String category; int number; String link; String numberStr; int numberStrLength; for (Element element : elements) { blogCategory = new BlogCategory(); category = element.select("a").text(); numberStr = element.select("span").text(); numberStrLength = numberStr.length(); number = Integer.valueOf(numberStr.substring(1, numberStrLength - 1)); link = element.select("a").attr("href"); blogCategory.setCategory(category); blogCategory.setNumber(number); blogCategory.setLink(BASE_PATH + link); blogCategoryList.add(blogCategory); } } } catch (IOException e) { e.printStackTrace(); } return blogCategoryList; } /** * 获取分类的链接后缀--例如,“Android”的链接后缀为“category/6094279” * * @param category 文章分类 * @return 后缀 */ private static String getCodeByCategory(String category) { List<BlogCategory> bgList = getBlogAllCategory(); if (bgList != null) { for (BlogCategory blogCategory : bgList) { if (blogCategory.getCategory().equals(category)) { String link = blogCategory.getLink(); int beginIndex = link.indexOf("category/"); return link.substring(beginIndex); } } } return ""; } /** * 获取指定分类下目录页数 * * @param category 分类 * @return 页数 */ private static int getCategoryPages(String category) { String code = getCodeByCategory(category); if (code.length() == 0) { return 0; } String suffix; Document doc; Elements pageList; String pages = "1"; suffix = "/article/" + code; try { doc = Jsoup.connect(BLOG_HOMEPAGE + suffix) .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31") .timeout(10000).get(); if (doc != null) { pageList = doc.select("div#papelist").select("span"); if (pageList != null && !"".equals(pageList.text())) { pages = pageList.text(); // 文章页数 pages = pages.substring(pages.indexOf("共") + 1, pages.indexOf("页")); } } } catch (Exception e) { e.printStackTrace(); } return Integer.valueOf(pages); } /** * 获取指定分类下指定页的博客简介 * * @param category 分类 * @param pages 页数 * @return 简介 */ public static List<BlogIntroduction> getOnePageBlogIntroductionByCategory(String category, int pages) { if (pages < 1) { return null; } if (pages > getCategoryPages(category)) { return null; } String code = getCodeByCategory(category); Document doc; Elements blogList; String suffix = "/article/" + code + "/" + pages; List<BlogIntroduction> blogIntroductionList = null; BlogIntroduction blogIntroduction; try { doc = Jsoup.connect(BLOG_HOMEPAGE + suffix) .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31") .timeout(10000).get(); blogList = doc.select("div#article_list > div"); if (blogList != null) { blogIntroductionList = new ArrayList<>(); for (Element blogItem : blogList) { blogIntroduction = new BlogIntroduction(); String title = blogItem.select("div.article_title > h1").text(); String description = blogItem.select("div.article_description").text(); String msg = blogItem.select("div.article_manage").text(); String link = BASE_PATH + blogItem.select("div.article_title > h1").select("span.link_title") .select("a").attr("href"); blogIntroduction.setTitle(title); blogIntroduction.setDescription(description); blogIntroduction.setMsg(msg); blogIntroduction.setUrl(link); blogIntroduction.setCategory(category); blogIntroductionList.add(blogIntroduction); } } } catch (IOException e1) { e1.printStackTrace(); } return blogIntroductionList; } /** * 按时间排列,获取指定页的博客简介 * * @param pages 页数 * @return 简介 */ public static List<BlogIntroduction> getOnePageBlogIntroductionByTime(int pages) { if (pages < 1) { return null; } int totalPages = getBlogPages(); if (pages > totalPages) { return null; } Document doc; Elements blogList; List<BlogIntroduction> blogIntroductionList = null; BlogIntroduction blogIntroduction; try { doc = Jsoup.connect(BLOG_HOMEPAGE + "/article/list/" + pages) .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31") .timeout(10000).get(); blogList = doc.select("div#article_list > div"); if (blogList != null) { blogIntroductionList = new ArrayList<>(); for (Element blogItem : blogList) { blogIntroduction = new BlogIntroduction(); String title = blogItem.select("div.article_title > h1").text(); String description = blogItem.select("div.article_description").text(); String msg = blogItem.select("div.article_manage").text(); String link = BASE_PATH + blogItem.select("div.article_title > h1").select("span.link_title") .select("a").attr("href"); blogIntroduction.setTitle(title); blogIntroduction.setDescription(description); blogIntroduction.setMsg(msg); blogIntroduction.setUrl(link); blogIntroduction.setCategory(""); blogIntroductionList.add(blogIntroduction); } } } catch (IOException e1) { e1.printStackTrace(); } return blogIntroductionList; } /** * 获取所有文章的页数 * * @return 页数 */ private static int getBlogPages() { Document doc; Elements pageList; String pages = "1"; try { doc = Jsoup.connect(BLOG_HOMEPAGE) .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31") .timeout(10000).get(); if (doc != null) { pageList = doc.select("div#papelist").select("span"); if (pageList != null && !"".equals(pageList.text())) { pages = pageList.text(); // 文章页数 pages = pages.substring(pages.indexOf("共") + 1, pages.indexOf("页")); } } } catch (Exception e) { e.printStackTrace(); pages = "0"; } return Integer.valueOf(pages); } /** * 获取博主文章简介-----如果是要获取所有文章,suffix="list/" * 如果是要获取某个分类的文章,suffix="category/"+一串数字 * * @param suffix 链接的后缀 * @return 内容 */ private static List<BlogIntroduction> getBlogIntroduction(String suffix) { Document doc; Elements pageList; Elements blogList; String nextUrl; suffix = "/article/" + suffix; String pages = "1"; List<BlogIntroduction> blogIntroductionList = null; BlogIntroduction blogIntroduction; try { doc = Jsoup.connect(BLOG_HOMEPAGE + suffix) .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31") .timeout(10000).get(); blogIntroductionList = new ArrayList<>(); if (doc != null) { pageList = doc.select("div#papelist").select("span"); if (pageList != null && !"".equals(pageList.text())) { pages = pageList.text(); // 文章页数 pages = pages.substring(pages.indexOf("共") + 1, pages.indexOf("页")); } for (int i = 1; i <= Integer.valueOf(pages); i++) { if (i != 1) { nextUrl = BLOG_HOMEPAGE + suffix + "/" + i; doc = Jsoup.connect(nextUrl) .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31") .timeout(10000).get(); } blogList = doc.select("div#article_list > div"); if (blogList != null) { for (Element blogItem : blogList) { blogIntroduction = new BlogIntroduction(); String title = blogItem.select("div.article_title > h1").text(); String description = blogItem.select("div.article_description").text(); String msg = blogItem.select("div.article_manage").text(); String link = BASE_PATH + blogItem.select("div.article_title > h1") .select("span.link_title").select("a").attr("href"); blogIntroduction.setTitle(title); blogIntroduction.setDescription(description); blogIntroduction.setMsg(msg); blogIntroduction.setUrl(link); blogIntroduction.setCategory(""); blogIntroductionList.add(blogIntroduction); } } } } } catch (IOException e) { e.printStackTrace(); } return blogIntroductionList; } /** * 根据链接获取博客内容 * * @param blogUrl url * @return 博客内容 */ public static List<BlogContent> getBlogContent(String blogUrl) { Document doc = null; Element element = null; try { doc = Jsoup.connect(blogUrl) .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31") .timeout(10000).get(); } catch (IOException e) { e.printStackTrace(); } if (doc != null) { // 获取标题区域 element = doc.select("div#article_details > div").first(); } if (element == null) { return null; } // 标题 String title = element.text(); // 获取总的内容区域下的所有子元素 Elements subElements = doc.select("div#article_content > div > *"); List<BlogContent> blogContents = new ArrayList<>(); BlogContent blogContent = new BlogContent(); blogContent.setType(BlogContent.enumContentType.BLOG_TITLE); blogContent.setContent(title); blogContents.add(blogContent); Elements imageElements; for (Element e : subElements) { blogContent = new BlogContent(); if (isRightType(e.tagName())) { String str = e.toString().replace("<br />", "#换行#").replace("<br>", "#换行#"); doc = Jsoup.parse(str); Element elem = doc.select(e.tagName()).first(); blogContent.setType(BlogContent.enumContentType.BLOG_TEXT); blogContent.setContent(elem.text().replace("#换行#", "\n").replace("\n\n", "\n").trim()); blogContents.add(blogContent); imageElements = e.select("img"); if (imageElements != null) { for (Element el : imageElements) { blogContent = new BlogContent(); blogContent.setType(BlogContent.enumContentType.BLOG_IMAGE); blogContent.setContent(el.attr("src")); blogContents.add(blogContent); } } } else if (e.tagName().equals("pre")) { blogContent.setType(BlogContent.enumContentType.BLOG_CODE); blogContent.setContent(e.text().replace("\n\n", "\n")); blogContents.add(blogContent); } } return blogContents; } private static boolean isRightType(String type) { return (type.equals("p") || type.equals("h1") || type.equals("h2") || type.equals("h3") || type.equals("h4") || type.equals("h5") || type.equals("h6") || type.equals("ul") || type.equals("ol") || type.equals("center")); } }Constants
public class Constants { /** * 博主名称 */ public static String BLOG_AUTHOR_NAME = "dt235201314"; /** * 博客目录 */ public static String DIRECTORY_1 = "Android 自定义View"; public static String DIRECTORY_2 = "TCL 雏鹰飞翔计划 · Android 篇"; public static String DIRECTORY_3 = "Android Github"; public static String DIRECTORY_4 = "我的毕业论文"; public static String DIRECTORY_5 = "Java 基础"; public static String DIRECTORY_6 = "java源码"; }MyCsdnActivity
侧滑实现参考:Android UI 之侧滑抽屉菜单(一)——DrawerLayout + NavigationView
public class MyCsdnActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { private DrawerLayout drawerLayout; // private CircleImageView circleImageView; private SimpleDraweeView top_image; private TextView tv_name, tv_originalArticleNumber, tv_visitNumber, tv_mark, tv_rank; private BlogAuthor blogAuthor; private String tvName, tvOriginalArticleNumber, tvVisitNumber, tvMark, tvRank; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Fresco.initialize(this); setContentView(R.layout.my_csdn_activity); initView(); } private void initView() { drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); top_image = (SimpleDraweeView) findViewById(R.id.top_image); NavigationView navigationView = (NavigationView) findViewById(R.id.navigationView); ViewPager viewPager = (ViewPager) findViewById(R.id.id_viewpager); PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(pagerAdapter); TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout); tabLayout.setupWithViewPager(viewPager); tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); View headerView = navigationView.getHeaderView(0); tv_name = (TextView) headerView.findViewById(R.id.tv_name); tv_originalArticleNumber = (TextView) headerView.findViewById(R.id.tv_originalArticleNumber); tv_visitNumber = (TextView) headerView.findViewById(R.id.tv_visitNumber); tv_mark = (TextView) headerView.findViewById(R.id.tv_mark); tv_rank = (TextView) headerView.findViewById(R.id.tv_rank); navigationView.setNavigationItemSelectedListener(this); navigationView.setItemIconTintList(null); top_image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { drawerLayout.openDrawer(GravityCompat.START); } }); new LoadImageAsync().execute(); //handler 处理返回的请求结果 handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); Bundle data = msg.getData(); String val = data.getString("value"); tv_name.setText(tvName); tv_originalArticleNumber.setText(tvOriginalArticleNumber); tv_visitNumber.setText(tvVisitNumber); tv_mark.setText(tvMark); tv_rank.setText(tvRank); Log.i("mylog", "请求结果-->" + val); } }; //新线程进行网络请求 Runnable runnable = new Runnable() { @Override public void run() { BlogAuthor blogAuthor = JsoupUtil.getBlogAutoMessage(); tvName = blogAuthor.getAuthorName() + "\n" + blogAuthor.getCode() + "\n" + blogAuthor.getMyHelloWorld(); tvOriginalArticleNumber = blogAuthor.getOriginalArticleNumber(); tvVisitNumber = blogAuthor.getVisitNumber(); tvMark = blogAuthor.getMark(); tvRank = blogAuthor.getRank(); Message msg = new Message(); Bundle data = new Bundle(); data.putString("value", "请求结果"); msg.setData(data); handler.sendMessage(msg); } }; new Thread(runnable).start(); //启动子线程 } /** * 菜单点击响应函数 * * @param item 菜单 * @return boolean */ @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { drawerLayout.closeDrawer(GravityCompat.START); switch (item.getItemId()) { case R.id.nav_csdn: WebViewActivity.startWebViewActivity(this, "http://my.csdn.net/dt235201314"); break; case R.id.nav_jianshu: WebViewActivity.startWebViewActivity(this, "http://www.jianshu.com/u/905c7de5ae83"); break; default: } return false; } /** * 重写返回键响应函数 */ @Override public void onBackPressed() { if (drawerLayout.isDrawerOpen(GravityCompat.START)) { drawerLayout.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } } /** * 用来加载主界面顶部头像以及侧边栏顶部头像 */ private class LoadImageAsync extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... params) { blogAuthor = JsoupUtil.getBlogAutoMessage(); String avatarUrl = ""; if (blogAuthor != null) { avatarUrl = blogAuthor.getAvatarUrl(); } return avatarUrl; } @Override protected void onPostExecute(String avatarUrl) { Uri uri = Uri.parse(avatarUrl); SimpleDraweeView top_image = (SimpleDraweeView) findViewById(R.id.top_image); SimpleDraweeView nav_head_image = (SimpleDraweeView) findViewById(R.id.nav_head_image); top_image.setImageURI(uri); nav_head_image.setImageURI(uri); } } }xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:fresco="http://schemas.android.com/apk/res-auto" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/blue_bg"> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/top_image" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentStart="true" android:layout_margin="5dp" fresco:placeholderImage="@drawable/mine_me" fresco:roundAsCircle="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="CSDN 博客" android:textColor="@android:color/black" android:textSize="20sp" android:textStyle="bold" /> </RelativeLayout> <android.support.design.widget.TabLayout android:id="@+id/tabLayout" style="@style/customTabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabIndicatorHeight="0dp" /> <android.support.v4.view.ViewPager android:id="@+id/id_viewpager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout> <android.support.design.widget.NavigationView android:id="@+id/navigationView" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header" app:menu="@menu/activity_main_drawer" /> </android.support.v4.widget.DrawerLayout>
public class BlogFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener, CommonViewHolder.onItemCommonClickListener { private View view; private SwipeRefreshLayout swipeRefreshLayout; public List<BlogIntroduction> blogIntroductionList; private BlogListAdapter blogListAdapter; //标记当前要加载的博客文章类型 private int blogType; //用来防止连续多次的网络请求 private boolean isGetting; //标记当前加载到的文章页数 private int currentLoadPage; private static final String BLOG_TYPE = "blogType"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.blogType = getArguments().getInt(BLOG_TYPE); } public static BlogFragment getBlogFragment(int blogType) { BlogFragment blogFragment = new BlogFragment(); Bundle bundle = new Bundle(); bundle.putInt(BLOG_TYPE, blogType); blogFragment.setArguments(bundle); return blogFragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (view == null) { view = inflater.inflate(R.layout.fragment_blog, container, false); swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefreshLayout); swipeRefreshLayout.setOnRefreshListener(this); RecyclerView rv_blogList = (RecyclerView) view.findViewById(R.id.rv_blogList); final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext()); rv_blogList.setLayoutManager(linearLayoutManager); blogIntroductionList = new ArrayList<>(); blogListAdapter = new BlogListAdapter(getContext(), blogIntroductionList, R.layout.item_blog, this); rv_blogList.setAdapter(blogListAdapter); swipeRefreshLayout.setRefreshing(true); rv_blogList.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { if (linearLayoutManager.findLastVisibleItemPosition() == blogIntroductionList.size() - 1) { new LoadMoreDataTask().execute(blogType); } } }); new RefreshDataTask().execute(blogType); } return view; } @Override public void onRefresh() { new RefreshDataTask().execute(blogType); } @Override public void onItemClickListener(int position) { WebViewActivity.startWebViewActivity(getActivity(),blogIntroductionList.get(position).getUrl()); } @Override public void onItemLongClickListener(int position) { } private class RefreshDataTask extends AsyncTask<Integer, Void, List<BlogIntroduction>> { @Override protected List<BlogIntroduction> doInBackground(Integer... params) { isGetting = true; List<BlogIntroduction> blogIntroductionList; if (params[0] == 0) { blogIntroductionList = JsoupUtil.getOnePageBlogIntroductionByTime(1); } else { blogIntroductionList = JsoupUtil.getOnePageBlogIntroductionByCategory(PagerAdapter.TAGS[params[0]], 1); } return blogIntroductionList; } @Override protected void onPostExecute(List<BlogIntroduction> tempBlogIntroductionList) { if (tempBlogIntroductionList != null && tempBlogIntroductionList.size() > 0) { blogIntroductionList.clear(); blogIntroductionList.addAll(tempBlogIntroductionList); currentLoadPage = 1; blogListAdapter.notifyDataSetChanged(); } else { Toast.makeText(getContext(), "数据获取不到啊~", Toast.LENGTH_SHORT).show(); } swipeRefreshLayout.setRefreshing(false); isGetting = false; } } private class LoadMoreDataTask extends AsyncTask<Integer, Void, List<BlogIntroduction>> { @Override protected List<BlogIntroduction> doInBackground(Integer... params) { //如果此时没有在进行获取数据的操作的话 if (!isGetting) { isGetting = true; if (params[0] == 0) { List<BlogIntroduction> list = JsoupUtil.getOnePageBlogIntroductionByTime(currentLoadPage + 1); if (list != null && list.size() > 0) { return list; } } else { List<BlogIntroduction> list = JsoupUtil.getOnePageBlogIntroductionByCategory(PagerAdapter.TAGS[params[0]], currentLoadPage + 1); if (list != null && list.size() > 0) { return list; } } return null; } // 已经在进行获取数据的操作的话则直接返回 return new ArrayList<>(); } @Override protected void onPostExecute(List<BlogIntroduction> tempBlogIntroductionList) { if (tempBlogIntroductionList == null) { isGetting = false; return; } if (tempBlogIntroductionList.size() == 0) { return; } blogIntroductionList.addAll(tempBlogIntroductionList); blogListAdapter.notifyDataSetChanged(); currentLoadPage++; isGetting = false; } } }xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/swipeRefreshLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/rv_blogList" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.v4.widget.SwipeRefreshLayout>adapter
public class BlogListAdapter extends CommonRecyclerAdapter<BlogIntroduction> { public BlogListAdapter(Context context, List<BlogIntroduction> dataList, int layoutId, CommonViewHolder.onItemCommonClickListener commonClickListener) { super(context, dataList, layoutId, commonClickListener); } @Override protected void bindData(CommonViewHolder holder, BlogIntroduction data) { holder.setText(R.id.tv_blogTitle, data.getTitle()) .setText(R.id.tv_blogIntroduction, data.getDescription()) .setText(R.id.tv_blogMessage, data.getMsg()); } }CommonRecyclerAdapter
public abstract class CommonRecyclerAdapter<T> extends RecyclerView.Adapter<CommonViewHolder> { private LayoutInflater layoutInflater; protected List<T> dataList; private int layoutId; public interface MultiTypeSupport<T> { int getLayoutId(T item, int position); } protected MultiTypeSupport<T> multiTypeSupport; protected CommonViewHolder.onItemCommonClickListener commonClickListener; protected CommonRecyclerAdapter(Context context, List<T> dataList) { this.layoutInflater = LayoutInflater.from(context); this.dataList = dataList; } protected CommonRecyclerAdapter(Context context, List<T> dataList, int layoutId) { this.layoutInflater = LayoutInflater.from(context); this.dataList = dataList; this.layoutId = layoutId; } protected CommonRecyclerAdapter(Context context, List<T> dataList, int layoutId, CommonViewHolder.onItemCommonClickListener commonClickListener) { this(context, dataList, layoutId); this.commonClickListener = commonClickListener; } protected CommonRecyclerAdapter(Context context, List<T> dataList, MultiTypeSupport<T> multiTypeSupport) { this(context, dataList); this.multiTypeSupport = multiTypeSupport; } protected CommonRecyclerAdapter(Context context, List<T> dataList, MultiTypeSupport<T> multiTypeSupport, CommonViewHolder.onItemCommonClickListener commonClickListener) { this(context, dataList, multiTypeSupport); this.commonClickListener = commonClickListener; } @Override public int getItemViewType(int position) { if (multiTypeSupport != null) { return multiTypeSupport.getLayoutId(dataList.get(position), position); } return super.getItemViewType(position); } @Override public CommonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (multiTypeSupport != null) { layoutId = viewType; } View itemView = layoutInflater.inflate(layoutId, parent, false); return new CommonViewHolder(itemView); } @Override public void onBindViewHolder(CommonViewHolder holder, int position) { bindData(holder, dataList.get(position)); holder.setCommonClickListener(commonClickListener); } @Override public int getItemCount() { return dataList.size(); } protected abstract void bindData(CommonViewHolder holder, T data); }CommonViewHolder
public class CommonViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { // SparseArray比HashMap更省内存,在某些条件下性能更好,只能存储key为int类型的数据 // 用来存放View以减少findViewById的次数 private SparseArray<View> viewSparseArray; public interface onItemCommonClickListener { void onItemClickListener(int position); void onItemLongClickListener(int position); } private onItemCommonClickListener commonClickListener; CommonViewHolder(View itemView) { super(itemView); viewSparseArray = new SparseArray<>(); itemView.setOnClickListener(this); itemView.setOnLongClickListener(this); } /** * 根据 ID 来获取 View * * @param viewId viewID * @param <T> 泛型 * @return 将结果强转为 View 或 View 的子类型 */ public <T extends View> T getView(int viewId) { // 先从缓存中找,找到的话则直接返回 // 如果找不到则findViewById,再把结果存入缓存中 View view = viewSparseArray.get(viewId); if (view == null) { view = itemView.findViewById(viewId); viewSparseArray.put(viewId, view); } return (T) view; } public CommonViewHolder setText(int viewId, CharSequence text) { TextView tv = getView(viewId); tv.setText(text); return this; } public CommonViewHolder setText(int viewId, SpannableString spannableString) { TextView textView = getView(viewId); textView.setText(spannableString); return this; } public CommonViewHolder setViewVisibility(int viewId, int visibility) { getView(viewId).setVisibility(visibility); return this; } public CommonViewHolder setImageResource(int viewId, int resourceId) { ImageView imageView = getView(viewId); imageView.setImageResource(resourceId); return this; } public CommonViewHolder setImageViewPadding(int viewId, int left, int top, int right, int bottom) { ImageView imageView = getView(viewId); imageView.setPadding(left, top, right, bottom); return this; } public void setImageViewOnClickListener(int viewId, View.OnClickListener onClickListener) { ImageView imageView = getView(viewId); imageView.setOnClickListener(onClickListener); } public void setTextViewOnLongClickListener(int viewId, View.OnLongClickListener onLongClickListener) { TextView textView = getView(viewId); textView.setOnLongClickListener(onLongClickListener); } public void setCommonClickListener(onItemCommonClickListener commonClickListener) { this.commonClickListener = commonClickListener; } @Override public void onClick(View v) { if (commonClickListener != null) { commonClickListener.onItemClickListener(getAdapterPosition()); } } @Override public boolean onLongClick(View v) { if (commonClickListener != null) { commonClickListener.onItemLongClickListener(getAdapterPosition()); } return false; } }WebViewActivity
public class WebViewActivity extends Activity { public static void startWebViewActivity (Context activity, String url) { Intent intent = new Intent(activity, WebViewActivity.class); intent.putExtra("url", url); activity.startActivity(intent); } /** * 启动WebViewActivity 静态方法 * @param activity Activity * @param title 标题 * @param url url * @param type 1:红包;其他待定义 */ public static void startWebViewActivity (Activity activity, String title, String url, int type) { Intent intent = new Intent(activity, WebViewActivity.class); intent.putExtra("title", title); intent.putExtra("url", url); intent.putExtra("type", type); activity.startActivity(intent); } private WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.webview_activity); createView(); } private void createView() { mWebView = (WebView) findViewById(R.id.wv_web); mWebView.getSettings().setDefaultFontSize(14); mWebView.getSettings().setUseWideViewPort(true); mWebView.getSettings().setLoadWithOverviewMode(true); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.getSettings().setDefaultTextEncodingName("UTF-8"); mWebView.loadUrl(getIntent().getStringExtra("url")); mWebView.setWebChromeClient(new WebChromeClient() { public void onProgressChanged(WebView view, int progress) { setProgress(progress * 100); } }); mWebView.setWebViewClient(new WebViewClient() { public boolean shouldOverrideUrlLoading(WebView view, String url) { // 重写此方法表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边 view.loadUrl(url); return true; } }); } public boolean onKeyDown(int keyCode, @Nullable KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { mWebView.goBack(); return true; } return super.onKeyDown(keyCode, event); } }四丶参考与延伸学习
Android 个人博客客户端——My CSDN 的实现(1)
五丶源码下载
如果文章对你有帮助,欢迎关注
https://github.com/JinBoy23520/CoderToDeveloperByTCLer