节目单左右滑动不好用,怎么办
先从动画开始看起
参考资料:
1. Android Animations - Tutorial
http://www.vogella.com/articles/AndroidAnimation/article.html
2. Is there any useful Android Animation Tutorial for beginners?
3. Android Fragments and animation
http://stackoverflow.com/questions/4817900/android-fragments-and-animation
通过ListView实现一个二级树
在频道列表的需要中有频道类别和频道两种数据。频道是频道类别的下级数据。每个频道类别可以保含多个频道。在界面上频道类别和频道用两种布局来表现。频道类别只有名称和箭头,频道类别展开时,箭头向下,频道类别收起来时,箭头向右。频道中的数据项比较多比如名称、图标、状态等。
新建TvChannelAdapter继承BaseAdapter。在构造方法中定义两个参数context表示上下文,categorys表示数据,然后将在界面上可见的频道类别和频道两类数据取出来保存在itemList中。itemList表示adapter中的数据。
先看TvChannelAdapter中几个比较简单点的方法
private Context context; private List<ChannelGroupData> categorys; private List<Object> itemList; private String selectChannelId = "000"; public TvChannelAdapter(Context context, List<ChannelGroupData> categorys) { this.context = context; this.categorys = categorys; this.initializeItemList(); } private void initializeItemList() { itemList = new ArrayList<Object>(); for (int i = 0; i < categorys.size(); i++) { ChannelGroupData category = categorys.get(i); itemList.add(category); if (category.isInExpanding()) itemList.addAll(category.getData()); } } @Override public void notifyDataSetChanged() { if (itemList != null) { itemList.clear(); itemList = null; } initializeItemList(); super.notifyDataSetChanged(); } @Override public int getCount() { return itemList.size(); } @Override public Object getItem(int position) { return itemList.get(position); } @Override public long getItemId(int position) { return position; }
再来看TvChannelAdapter中很关键的方法getView。由于listView中要表现两种类型的数据,所以在getView方法中就要构造出两种类型的view。其中频道类别view用item_tvchannel_category.xml来构建,频道view用item_tvchannel_child.xml来构建。getView方法中返回的每个view的都来自itemList中的数据,view和数据用position关联对应。
public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = new ViewHolder(); if (itemList.get(position) instanceof ChannelItemData) { convertView = LayoutInflater.from(context).inflate(R.layout.item_tvchannel_child, null); initializeItemViewHolder(viewHolder, (ChannelItemData) itemList.get(position), convertView); } else { convertView = LayoutInflater.from(context).inflate(R.layout.item_tvchannel_category, null); initializeCategoryViewHolder(viewHolder, position, convertView); } return convertView; }
在getView方法中有个Viewholder。它的定义如下,包含convertView中所有用到的view项。
private static class ViewHolder { AsyncImageView channelIcon; TextView channelName; TextView channelStatus; TextView categoryName; ImageView btnExpand; }
当数据类型是频道类别时,调用initxxx来构建频道类别view中的内容。
频道类别点击时可以展开或者收起下级的频道。
private void initializeCategoryViewHolder(final ViewHolder viewHolder, final int position, View convertView) { final ChannelGroupData category = (ChannelGroupData) itemList.get(position); viewHolder.categoryName = (TextView) convertView.findViewById(R.id.channelGroupTitleName); viewHolder.btnExpand = (ImageView) convertView.findViewById(R.id.btnExpand); viewHolder.categoryName.setText(category.getName()); viewHolder.btnExpand.setImageResource(category.isInExpanding() ? R.drawable.channel_expand_btn : R.drawable.channel_shrink_btn); viewHolder.btnExpand.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if(category.isInExpanding()) { category.setInExpanding(false); } else { category.setInExpanding(true); shrinkOtherGroupTitle(position); } notifyDataSetChanged(); } }); convertView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { viewHolder.btnExpand.performClick(); } }); } public void shrinkOtherGroupTitle(int position) { for (int i = 0; i < itemList.size(); i++) { if (itemList.get(i) instanceof ChannelGroupData) { ((ChannelGroupData) itemList.get(i)).setInExpanding(i == position); } } }
当数据类型表现为频道时,频道view也有个点击事件,点击时记下频道的id,然后调用notifyDataSetChanged方法,将点击的那个频道设置背景颜色表示选中状态。
private void initializeItemViewHolder(ViewHolder viewHolder, final ChannelItemData item, View convertView) { String hint = context.getResources().getString(R.string.live_play); String liveName = item.getLiveEpg().getName(); if (TextUtils.isEmpty(liveName) || liveName.equalsIgnoreCase("null")) liveName = "(未知)"; viewHolder.channelIcon = (AsyncImageView) convertView.findViewById(R.id.channelIcon); viewHolder.channelName = (TextView) convertView.findViewById(R.id.channelName); viewHolder.channelStatus = (TextView) convertView.findViewById(R.id.channelStatus); viewHolder.channelIcon.setCleartrue); viewHolder.channelIcon.setUrl(item.getIcon()); viewHolder.channelName.setText(item.getName()); viewHolder.channelStatus.setVisibility(View.VISIBLE); viewHolder.channelStatus.setText(hint + liveName); if(selectChannelId.equals(item.getChannelId())) convertView.setBackgroundColor(context.getResources().getColor(R.color.lightblue)); else convertView.setBackgroundColor(context.getResources().getColor(R.color.default_backgroud_color)); convertView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(item.getCategoryId() != null) { selectChannelId = item.getChannelId(); notifyDataSetChanged(); } } }); }