客户端上显示csdn上的各类别下的的文章列表 (制作csdn app 三)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/23597229
今天将在Android 使用Fragment,ViewPagerIndicator 制作csdn app主要框架和抓取csdn上的各类别的文章 (制作csdn app 二)这两篇的基础之上,继续完善我们的项目。
今天的目标效果:
好了,说下今天的主要任务:引入XlistView,然后对从网络上获取的数据进行显示,说起来还是挺轻松的,不过咱们的app看起来已经很不错了。
进入正题。
1、首先当然是实现承诺,把我们第二篇博客中的制作好的jar引入我们的项目。
注意我们的csdn_splider.jar依赖于jsoup.jar,不但两个都需要引入,而且需要jsoup在前,不然可能会报ClassNotFoundException。
2、MainActivity没有变化,但还是贴一下代码,方便大家的理解。
package com.zhy.csdndemo; import com.viewpagerindicator.TabPageIndicator; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; public class MainActivity extends FragmentActivity { private TabPageIndicator mIndicator ; private ViewPager mViewPager ; private FragmentPagerAdapter mAdapter ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mIndicator = (TabPageIndicator) findViewById(R.id.id_indicator); mViewPager = (ViewPager) findViewById(R.id.id_pager); mAdapter = new TabAdapter(getSupportFragmentManager()); mViewPager.setAdapter(mAdapter); mIndicator.setViewPager(mViewPager, 0); } }
主要的工作都是在MainFragment.java中完成。
package com.zhy.csdndemo; import java.util.ArrayList; import java.util.List; import me.maxwin.view.IXListViewLoadMore; import me.maxwin.view.IXListViewRefreshListener; import me.maxwin.view.XListView; import android.annotation.SuppressLint; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.zhy.bean.CommonException; import com.zhy.bean.NewsItem; import com.zhy.biz.NewsItemBiz; import com.zhy.csdn.Constaint; import com.zhy.csdndemo.adapter.NewsItemAdapter; @SuppressLint("ValidFragment") public class MainFragment extends Fragment implements IXListViewRefreshListener, IXListViewLoadMore { /** * 默认的newType */ private int newsType = Constaint.NEWS_TYPE_YEJIE; /** * 当前页面 */ private int currentPage = 1; /** * 处理新闻的业务类 */ private NewsItemBiz mNewsItemBiz; /** * 扩展的ListView */ private XListView mXListView; /** * 数据适配器 */ private NewsItemAdapter mAdapter; /** * 数据 */ private List<NewsItem> mDatas = new ArrayList<NewsItem>(); /** * 获得newType * @param newsType */ public MainFragment(int newsType) { this.newsType = newsType; mNewsItemBiz = new NewsItemBiz(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.tab_item_fragment_main, null); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mAdapter = new NewsItemAdapter(getActivity(), mDatas); /** * 初始化 */ mXListView = (XListView) getView().findViewById(R.id.id_xlistView); mXListView.setAdapter(mAdapter); mXListView.setPullRefreshEnable(this); mXListView.setPullLoadEnable(this); //mXListView.NotRefreshAtBegin(); /** * 进来时直接刷新 */ mXListView.startRefresh(); } @Override public void onRefresh() { new LoadDatasTask().execute(); } @Override public void onLoadMore() { // TODO Auto-generated method stub } /** * 记载数据的异步任务 * @author zhy * */ class LoadDatasTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { try { List<NewsItem> newsItems = mNewsItemBiz.getNewsItems(newsType, currentPage); mDatas = newsItems; } catch (CommonException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void result) { mAdapter.addAll(mDatas); mAdapter.notifyDataSetChanged(); mXListView.stopRefresh(); } } }
MainActivity中需要一个数据适配器,也就是NewsItemAdapter.java
package com.zhy.csdndemo.adapter; import java.util.List; import android.content.Context; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer; import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer; import com.zhy.bean.NewsItem; import com.zhy.csdn.DataUtil; import com.zhy.csdndemo.R; public class NewsItemAdapter extends BaseAdapter { private LayoutInflater mInflater; private List<NewsItem> mDatas; /** * 使用了github开源的ImageLoad进行了数据加载 */ private ImageLoader imageLoader = ImageLoader.getInstance(); private DisplayImageOptions options; public NewsItemAdapter(Context context, List<NewsItem> datas) { this.mDatas = datas; mInflater = LayoutInflater.from(context); imageLoader.init(ImageLoaderConfiguration.createDefault(context)); options = new DisplayImageOptions.Builder().showStubImage(R.drawable.images) .showImageForEmptyUri(R.drawable.images).showImageOnFail(R.drawable.images).cacheInMemory() .cacheOnDisc().displayer(new RoundedBitmapDisplayer(20)).displayer(new FadeInBitmapDisplayer(300)) .build(); } public void addAll(List<NewsItem> mDatas) { this.mDatas.addAll(mDatas); } @Override public int getCount() { return mDatas.size(); } @Override public Object getItem(int position) { return mDatas.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = mInflater.inflate(R.layout.news_item_yidong, null); holder = new ViewHolder(); holder.mContent = (TextView) convertView.findViewById(R.id.id_content); holder.mTitle = (TextView) convertView.findViewById(R.id.id_title); holder.mDate = (TextView) convertView.findViewById(R.id.id_date); holder.mImg = (ImageView) convertView.findViewById(R.id.id_newsImg); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } NewsItem newsItem = mDatas.get(position); holder.mTitle.setText(DataUtil.ToDBC(newsItem.getTitle())); holder.mContent.setText(newsItem.getContent()); holder.mDate.setText(newsItem.getDate()); if (newsItem.getImgLink() != null) { holder.mImg.setVisibility(View.VISIBLE); imageLoader.displayImage(newsItem.getImgLink(), holder.mImg, options); } else { holder.mImg.setVisibility(View.GONE); } return convertView; } private final class ViewHolder { TextView mTitle; TextView mContent; ImageView mImg; TextView mDate; } }
对于Listview的每个Item的布局,这样的写法也很常见了,所以都不多说了,注意一点就行,这里对图片的加载用的是Github上的ImageLoader项目。
3、Frament的布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <me.maxwin.view.XListView android:id="@+id/id_xlistView" android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="#00000000" android:divider="@drawable/base_list_divider_drawable" android:fadingEdge="none" > </me.maxwin.view.XListView> </RelativeLayout>
XlistView的Item的布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="8dp" android:paddingBottom="8dp" > <TextView android:id="@+id/id_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:textSize="18sp" android:textColor="@color/black" android:text="如何有效地在海外市场推广产品?"/> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:baselineAligned="true" > <ImageView android:id="@+id/id_newsImg" android:src="@drawable/images" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dp" android:visibility="visible"/> <LinearLayout android:layout_width="0dp" android:layout_height="fill_parent" android:layout_gravity="center_vertical" android:layout_weight="1" android:gravity="center_vertical" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="top" > <TextView android:id="@+id/id_content" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="top" android:maxLines="2" android:text="3D打印机一直以来只能进行单向操作,任务一旦开始便无法反悔。不过最近一批研究生研发了一种新型打印机,让你在打印的同时,可以修改重塑之前的设计。让我们一起来看看这个神奇的设备究竟是怎样的吧。" android:textColor="@color/nomalGray" android:textSize="14sp" /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical" > <TextView android:id="@+id/id_date" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical|right" android:paddingTop="8dp" android:singleLine="true" android:text="13分钟前|11次阅读" android:textSize="12sp" android:textColor="@color/nomalGray" /> <TextView android:id="@+id/id" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:paddingTop="16dp" android:text="1" android:gravity="right" android:visibility="gone" android:textColor="@color/nomalGray" /> </LinearLayout> </LinearLayout> </LinearLayout> <!-- <TextView android:id="@+id/availableNum" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/nomalGray" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:background="@drawable/bg_mark_pressed" android:text="可借:4" android:textSize="13sp" android:layout_marginLeft="2dp" android:layout_marginRight="2dp" android:layout_centerVertical="true" /> --> </LinearLayout>
好了,到此结束,总体来说还是比较容易实现的,不过可以看到进展的感觉不错。
源码点击此处下载