好久没有更新博客了。
最近由于工作比较忙,再加上忙于社交。导致一直没好好静下来研究Android。
这次给大家分享“仿腾讯新闻内容列表界面”。其实,这段代码已经写了一阵时间了,只是很久没有传上来,这次借好不容易静下来的机会将其贴上来,分享其中一些技术。大家可以给出意见或建议,感谢。
此文只是初期对新闻客户端的布局设计。不管是前端UI还是后台设计,后续会一点一点丰富起来。
文中主要用到的技术:
1、ListView列表
2、各类不同列表项的布局
3、BaseAdapter继承类的应用
众所周知,腾讯新闻客户端主界面是这样的:
这次要防的是导航条下面的列表布局,仿后的效果图:
布局原理:可以将整个界面看做一个列表容器(ListView,程序中也确实如此),UI方面有多种布局,每一哥条目不同则布局不同(目前定义了4种新闻条目布局:1、顶部新闻;2、常规新闻;3、3图新闻;4、推广性新闻)。Data方面,每一个条目就是一条新闻对象,不同的新闻对象定义不同, 抽取其相同的共性进行继承。可以理解为:
*后台数据对象 ----(驱动)---->UI界面显示*
1、主界面布局 activity_main.xml
<ListView android:id="@+id/myList" android:layout_width="match_parent" android:layout_height="match_parent" android:headerDividersEnabled="false" xmlns:android="http://schemas.android.com/apk/res/android"></ListView>
就是简单的一个列表View。以后的设计,会将这一块作为一个module,嵌入到主界面中。
其对应的主Activity:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListView listView = (ListView) findViewById(R.id.myList); List<NewsItem> newsItemList = getTestData(); listView.setAdapter(new NewsItemAdapter(this, newsItemList)); } private List<NewsItem> getTestData() { List<NewsItem> newsItemList = new ArrayList<>(); Resources resources = getResources(); TopNewsItem topNewsItem = new TopNewsItem(); topNewsItem.setBgImageBitmap(BitmapFactory.decodeResource(resources, R.drawable.laoren)); topNewsItem.setTitleImageBitmap(BitmapFactory.decodeResource(resources, R.drawable.global_icon_tag_pic)); topNewsItem.setTitle("老人晚年无人照顾,流泪哭诉"); topNewsItem.setItemType(ItemType.TOP_ONE_PICTURE); NormalNewsItem normalNewsItem = new NormalNewsItem(); normalNewsItem.setItemType(ItemType.NORMAL_SINGLE_PICTURE); normalNewsItem.setTitle("这是一个好新闻"); normalNewsItem.setCommentNum(99); normalNewsItem.setCommentNumImageBitMap(BitmapFactory.decodeResource(resources,R.drawable.flag_scoop_icon)); normalNewsItem.setDescription("点击查看灰常拉风炫酷的一辆车,便宜又好用。"); normalNewsItem.setLeftImageBitMap(BitmapFactory.decodeResource(resources,R.drawable.car1)); ThreePictureNewsItem threePictureNewsItem = new ThreePictureNewsItem(); threePictureNewsItem.setCommentNum(88); threePictureNewsItem.setTitle("好多图片呢,哈哈"); threePictureNewsItem.setCommentImageBitmap(BitmapFactory.decodeResource(resources,R.drawable.flag_special_icon)); threePictureNewsItem.setFirstImageBitmap(BitmapFactory.decodeResource(resources,R.drawable.benz1)); threePictureNewsItem.setSecondImageBitmap(BitmapFactory.decodeResource(resources,R.drawable.jiebao1)); threePictureNewsItem.setThirdImageBitmap(BitmapFactory.decodeResource(resources,R.drawable.car1)); threePictureNewsItem.setPictureNum(99); threePictureNewsItem.setItemType(ItemType.NORMAL_3_PICTURE); PromotionNewsItem promotionNewsItem = new PromotionNewsItem(); promotionNewsItem.setItemType(ItemType.NORMAL_PROMOTION); promotionNewsItem.setTitle("部落战争,等你来战!"); promotionNewsItem.setTitleIconBitmap(BitmapFactory.decodeResource(resources,R.drawable.head_flag_ad_icon)); promotionNewsItem.setImageBitmap(BitmapFactory.decodeResource(resources,R.drawable.buluochongtu)); newsItemList.add(topNewsItem); newsItemList.add(normalNewsItem); newsItemList.add(threePictureNewsItem); newsItemList.add(promotionNewsItem); return newsItemList; } }
可以看到这里大部分代码是写的测试代码,通过添加新闻对象驱动UI显示。这部分后面会设计加入网络爬虫程序驱动生成新闻条目对象。
2、新闻适配器,关键代码:NewsItemAdapter.java
public class NewsItemAdapter extends BaseAdapter { private LayoutInflater mLayoutInflater = null; private List<NewsItem> mNewsItems = null; public NewsItemAdapter(Context context, List<NewsItem> newsItemList) { this.mLayoutInflater = LayoutInflater.from(context); this.mNewsItems = newsItemList; } @Override public int getCount() { return null != mNewsItems ? mNewsItems.size() : 0; } @Override public NewsItem getItem(int position) { if (null != mNewsItems) return mNewsItems.get(position); return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { NewsItem newsItem = getItem(position); ViewHolder viewHolder = null; View view = convertView; if (null == convertView) { view = getItemLayoutView(newsItem); viewHolder = initView(view); view.setTag(viewHolder); } else { viewHolder = (ViewHolder) view.getTag(); } //单图片的Item if (newsItem.getItemType() == ItemType.NORMAL_SINGLE_PICTURE) { NormalNewsItem normalNewsItem = (NormalNewsItem) newsItem; viewHolder.getSinglePicView().titleTextView.setText(normalNewsItem.getTitle()); viewHolder.getSinglePicView().picImageView.setImageBitmap(normalNewsItem.getLeftImageBitMap()); viewHolder.getSinglePicView().commentIcon.setImageBitmap(normalNewsItem.getCommentNumImageBitMap()); viewHolder.getSinglePicView().contentTextView.setText(normalNewsItem.getDescription()); viewHolder.getSinglePicView().commentNumTextView.setText(normalNewsItem.getCommentNum() + "评"); } else if (newsItem.getItemType() == ItemType.NORMAL_3_PICTURE) { ThreePictureNewsItem threePictureNewsItem = (ThreePictureNewsItem) newsItem; viewHolder.getThreePicView().titleTextView.setText(threePictureNewsItem.getTitle()); viewHolder.getThreePicView().picNumTextView.setText(threePictureNewsItem.getPictureNum() + "图"); viewHolder.getThreePicView().picCommentTextView.setText(threePictureNewsItem.getCommentNum() + "评"); viewHolder.getThreePicView().picCommentImageView.setImageBitmap(threePictureNewsItem.getCommentImageBitmap()); viewHolder.getThreePicView().firstImageView.setImageBitmap(threePictureNewsItem.getFirstImageBitmap()); viewHolder.getThreePicView().secondImageView.setImageBitmap(threePictureNewsItem.getSecondImageBitmap()); viewHolder.getThreePicView().thirdImageView.setImageBitmap(threePictureNewsItem.getThirdImageBitmap()); } else if (newsItem.getItemType() == ItemType.NORMAL_PROMOTION) { PromotionNewsItem promotionNewsItem = (PromotionNewsItem) newsItem; viewHolder.getPromotionView().titleTextView.setText(promotionNewsItem.getTitle()); viewHolder.getPromotionView().promotionImageView.setImageBitmap(promotionNewsItem.getImageBitmap()); viewHolder.getPromotionView().promotionIcon.setImageBitmap(promotionNewsItem.getTitleIconBitmap()); } else if (newsItem.getItemType() == ItemType.TOP_ONE_PICTURE) { TopNewsItem topNewsItem = (TopNewsItem) newsItem; viewHolder.getTopView().titleTextView.setText(topNewsItem.getTitle()); viewHolder.getTopView().titleIcon.setImageBitmap(topNewsItem.getTitleImageBitmap()); viewHolder.getTopView().bkgImageView.setImageBitmap(topNewsItem.getBgImageBitmap()); } return view; } private ViewHolder initView(View view) { ViewHolder viewHolder; viewHolder = new ViewHolder(); viewHolder.getThreePicView().firstImageView = (ImageView) view.findViewById(R.id.firstPic); viewHolder.getThreePicView().secondImageView = (ImageView) view.findViewById(R.id.secondPic); viewHolder.getThreePicView().thirdImageView = (ImageView) view.findViewById(R.id.thirdPic); viewHolder.getThreePicView().picCommentImageView = (ImageView) view.findViewById(R.id.threePicCommentPic); viewHolder.getThreePicView().picCommentTextView = (TextView) view.findViewById(R.id.threePicCommentNum); viewHolder.getThreePicView().picNumTextView = (TextView) view.findViewById(R.id.threePicNum); viewHolder.getThreePicView().titleTextView = (TextView) view.findViewById(R.id.threePicTitle); viewHolder.getPromotionView().promotionIcon = (ImageView) view.findViewById(R.id.promotionIcon); viewHolder.getPromotionView().promotionImageView = (ImageView) view.findViewById(R.id.promotionImage); viewHolder.getPromotionView().titleTextView = (TextView) view.findViewById(R.id.promotionTitle); viewHolder.getSinglePicView().commentIcon = (ImageView) view.findViewById(R.id.singlePicCommentPic); viewHolder.getSinglePicView().commentNumTextView = (TextView) view.findViewById(R.id.singlePicCommentNum); viewHolder.getSinglePicView().contentTextView = (TextView) view.findViewById(R.id.singlePicNewsContent); viewHolder.getSinglePicView().picImageView = (ImageView) view.findViewById(R.id.singleImage); viewHolder.getSinglePicView().titleTextView = (TextView) view.findViewById(R.id.singlePicNewsTitle); viewHolder.getTopView().bkgImageView = (ImageView) view.findViewById(R.id.bkgImageView); viewHolder.getTopView().titleIcon = (ImageView) view.findViewById(R.id.topViewIcon); viewHolder.getTopView().titleTextView = (TextView) view.findViewById(R.id.topViewText); return viewHolder; } private View getItemLayoutView(NewsItem newsItem) { View view = null; if (newsItem.getItemType() == ItemType.NORMAL_SINGLE_PICTURE) { view = mLayoutInflater.inflate(R.layout.item_single_pic, null); } else if (newsItem.getItemType() == ItemType.NORMAL_3_PICTURE) { view = mLayoutInflater.inflate(R.layout.item_3_pic, null); } else if (newsItem.getItemType() == ItemType.NORMAL_PROMOTION) { view = mLayoutInflater.inflate(R.layout.item_promotion, null); } else if (newsItem.getItemType() == ItemType.TOP_ONE_PICTURE) { view = mLayoutInflater.inflate(R.layout.item_top, null); } else { return null; } return view; } private static class ViewHolder { public class ThreePicView { public TextView titleTextView = null; public ImageView firstImageView = null; public ImageView secondImageView = null; public ImageView thirdImageView = null; public TextView picNumTextView = null; public TextView picCommentTextView = null; public ImageView picCommentImageView = null; } public class PromotionView { public TextView titleTextView = null; public ImageView promotionImageView = null; public ImageView promotionIcon = null; } public class SinglePicView { public TextView titleTextView = null; public ImageView picImageView = null; public TextView contentTextView = null; public TextView commentNumTextView = null; public ImageView commentIcon = null; } public class TopView { public TextView titleTextView = null; public ImageView titleIcon = null; public ImageView bkgImageView = null; } private ThreePicView threePicView = null; private PromotionView promotionView = null; private SinglePicView singlePicView = null; private TopView topView = null; public ThreePicView getThreePicView() { if (null == threePicView) { threePicView = new ThreePicView(); } return threePicView; } public PromotionView getPromotionView() { if (null == promotionView) { promotionView = new PromotionView(); } return promotionView; } public SinglePicView getSinglePicView() { if (null == singlePicView) { singlePicView = new SinglePicView(); } return singlePicView; } public TopView getTopView() { if (null == topView) { topView = new TopView(); } return topView; } } }
新闻适配器的主要工作是将UI组件与java程序对象进行绑定,这里不涉及到新闻(业务)内容,而是适配新闻内容。此处定义了一个Viewholder内部类,是绑定前台组件的惯用写法。静态内部类好处大家可以搜下相关资料,此处不再赘述。
该篇仅仅是对仿腾讯新闻客户端的一个开始,仅实现了布局界面,后续会陆续加入:
界面导航条
后台数据系统(思路:单独系统,新闻爬虫,爬取腾讯相关新闻,并实现远程访问)
数据静态化、本地化
…