鱼鱼Chen之学写自己的apk(六)ListView带动画图标

来源:互联网 发布:淘宝客户 编辑:程序博客网 时间:2024/06/01 08:03

一个简易的ListView还是很好写的,不过这个demo我还是花了一些功夫,有些判断确实让我想了一番。当然了,这样更更好地演示listview的用法。


一、分析结构

主Activity,一个自定义的集合类,还有一个自定义的Listview适配器。布局就是主布局和listview项布局。


二、建立集合类

从一开始的截图可以看出,我们需要三个参数,英雄图片,名字,还有描述。于是如下,主要是写构造方法,以及提供get方法调用(提供给适配器的)

public class ListViewItem {private int image;private String name;private String description;public ListViewItem(int image, String name, String description) {this.image = image;this.name = name;this.description = description;}public int getImage() {return image;}public String getName() {return name;}public String getDescription() {return description;}}
这个就不多解释了,没什么难度。

二、写好适配器的构造方法

这里我们可以参考之前学的自定义Spinner那一节的方法

构造方法如下:

public ListViewItemAdapter(Context context, int resourceId,List<ListViewItem> items) {super(context, resourceId, items);this.mContext = context;this.resourceId = resourceId;}
三、回到主Activity

private void init() {listView = (ListView) findViewById(R.id.listView);items = new ArrayList<ListViewItem>();addItems();adapter = new ListViewItemAdapter(MainActivity.this,R.layout.listview_layout, items);listView.setAdapter(adapter);listView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {adapter.setCurrentIndex(position);adapter.notifyDataSetChanged();}});}
以上是初始化的,我为listview绑了一个列表项点击监听器,里面的代码先不解释,之后说。

上面的addItems方法如下,就是用来内部添加元素的

private void addItems() {items.add(new ListViewItem(pics[0], "斧王", getResources().getString(R.string.strHero)));items.add(new ListViewItem(pics[1], "祈求者", getResources().getString(R.string.intHero)));items.add(new ListViewItem(pics[2], "小精灵", getResources().getString(R.string.intHero)));items.add(new ListViewItem(pics[3], "主宰", getResources().getString(R.string.dexHero)));items.add(new ListViewItem(pics[4], "变体精灵", getResources().getString(R.string.dexHero)));items.add(new ListViewItem(pics[5], "瘟疫法师", getResources().getString(R.string.intHero)));items.add(new ListViewItem(pics[6], "痛苦女王", getResources().getString(R.string.intHero)));items.add(new ListViewItem(pics[7], "影魔", getResources().getString(R.string.dexHero)));items.add(new ListViewItem(pics[8], "沉默术士", getResources().getString(R.string.intHero)));items.add(new ListViewItem(pics[9], "天怒法师", getResources().getString(R.string.intHero)));items.add(new ListViewItem(pics[10], "斯拉克", getResources().getString(R.string.dexHero)));items.add(new ListViewItem(pics[11], "风暴之灵", getResources().getString(R.string.intHero)));items.add(new ListViewItem(pics[12], "圣堂刺客", getResources().getString(R.string.dexHero)));items.add(new ListViewItem(pics[13], "巨魔战将", getResources().getString(R.string.dexHero)));items.add(new ListViewItem(pics[14], "寒冬飞龙", getResources().getString(R.string.intHero)));}
相关的知识点,前几次都说了。即list<集合类>以及getResource的用法。


四、重新回到适配器,先看xml文件

对了,忘了上主Activity的xml文件,没什么难度,直接上代码

<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"    tools:context="com.dota.example.fishychenoflistview.MainActivity" >    <ListView        android:id="@+id/listView"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_above="@+id/linearLayout_bottm" />    <LinearLayout        android:id="@+id/linearLayout_bottm"        android:layout_width="match_parent"        android:layout_height="60dp"        android:layout_alignParentBottom="true"        android:background="@drawable/background"        android:orientation="vertical"        android:padding="16dp" >        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="我是可爱的底部栏"            android:textSize="18sp"            android:layout_gravity="center_horizontal"/>    </LinearLayout></RelativeLayout>
下面是listview的布局xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@drawable/background_selector">    <RelativeLayout        android:id="@+id/relativeLayout_top"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:paddingBottom="8dp"        android:paddingTop="8dp" >        <LinearLayout            android:id="@+id/item_selected"            android:layout_width="8dp"            android:layout_height="wrap_content"            android:layout_alignTop="@+id/item_image"            android:layout_alignBottom="@+id/item_image"            android:layout_marginTop="6dp"            android:layout_marginBottom="6dp"            android:background="@android:color/holo_blue_light"            android:orientation="vertical"            android:visibility="invisible" />        <ImageView            android:id="@+id/item_image"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentTop="true"            android:layout_toRightOf="@+id/item_selected"/>        <TextView            android:id="@+id/item_name"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerVertical="true"            android:layout_marginLeft="8dp"            android:layout_toRightOf="@+id/item_image"            android:textSize="22sp" />        <ImageView            android:id="@+id/item_icon"            android:layout_width="36dp"            android:layout_height="36dp"            android:layout_alignParentRight="true"            android:layout_centerVertical="true"            android:src="@drawable/time_setting_right_unselected" />    </RelativeLayout>    <RelativeLayout        android:id="@+id/relativeLayout_bottom"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/relativeLayout_top"        android:background="@android:color/black" >        <TextView            android:id="@+id/item_description"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerInParent="true"            android:textColor="@android:color/white"            android:textSize="16sp"            android:visibility="gone" />    </RelativeLayout></RelativeLayout>
还是这样看的最清楚!

主布局嵌了两层,第二层是用来显示描述的,默认view.gone。第一层,分别是一个选中显示的小蓝条,默认隐藏(之前在MainActivity里写的算法就是用来显示选中的显示蓝条)。剩下的几个分别是头像,名字,小三角图像。

五、分析适配器的getView方法

先上代码

@Overridepublic View getView(final int position, View convertView, ViewGroup parent) {item = getItem(position);View view;if (convertView == null) {view = LayoutInflater.from(mContext).inflate(resourceId, parent,false);holder = new ViewHolder();holder.select = (LinearLayout) view.findViewById(R.id.item_selected);holder.image = (ImageView) view.findViewById(R.id.item_image);holder.icon = (ImageView) view.findViewById(R.id.item_icon);holder.icon.setTag(false);holder.name = (TextView) view.findViewById(R.id.item_name);holder.description = (TextView) view.findViewById(R.id.item_description);view.setTag(holder);} else {view = convertView;holder = (ViewHolder) view.getTag();}holder.description.setText(item.getDescription());holder.description.setVisibility(View.GONE);holder.image.setBackgroundResource(item.getImage());if ((lastIconIndex == position) && iconFlag) {iconFlag = false;holder.icon.setImageResource(R.drawable.time_setting_right_unselected_2);Animation animation = new RotateAnimation(0, -90,holder.icon.getWidth() / 2, holder.icon.getHeight() / 2);animation.setDuration(200);animation.setFillAfter(true);holder.icon.startAnimation(animation);}if ((iconIndex == position) && iconFlag2) {iconFlag2 = false;if (lastIconIndex != iconIndex) {holder.icon.setImageResource(R.drawable.time_setting_right_unselected);Animation animation = new RotateAnimation(0, 90,holder.icon.getWidth() / 2, holder.icon.getHeight() / 2);animation.setDuration(200);animation.setFillAfter(true);holder.icon.startAnimation(animation);animation.setAnimationListener(new AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animation animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationEnd(Animation animation) {notifyDataSetChanged();}});}} else {if ((iconIndex == position) && (iconFlag2 == false)) {holder.description.setVisibility(View.VISIBLE);}}holder.icon.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {lastIconIndex = iconIndex;iconIndex = position;iconFlag = true;iconFlag2 = true;notifyDataSetChanged();}});holder.name.setText(item.getName());holder.select.setVisibility(View.INVISIBLE);if (currentIndex == position) {holder.select.setVisibility(View.VISIBLE);}return view;}}
其实并不复杂,根据position来遍历整个列表项。而整个列表项集合就是我们之前提供的list。

关于ViewHolder的使用,之前也说过了,是为了让有缓存过得快速加载,再利用,防止卡。

viewholder类,以及声明

class ViewHolder {LinearLayout select;ImageView image, icon;TextView name, description;}
private Context mContext;private int resourceId;private ListViewItem item;private ViewHolder holder;private int currentIndex = -1;private int iconIndex = -1;private int lastIconIndex = -1;private boolean iconFlag = false;private boolean iconFlag2 = false;
先得到列表项对象
item = getItem(position);
对应的,通过之前自定义集合类的封装好的方法得到参数

holder.description.setText(item.getDescription());holder.description.setVisibility(View.GONE);holder.image.setBackgroundResource(item.getImage());
其实呢,这样listview的基本使用就完成了。切记!!listview在主布局中,长、高要用match_parent,用了wrap_content的话,会造成多次刷新的问题。之后会造成判定时不必要的麻烦。

不过,我另外加了一些效果。类似于酷狗音乐的音乐表单。就是动画效果做的有点简陋,下拉的隐藏布局做的不太美观,毕竟时间有限(都大三了为什么还有那么多课和作业T^T)。

完整的getView方法上面有,就不重复上了。简单提一下,通过设置一个int 参数,然后在你要判定的事件里,给int参数赋值,并调用notifyDataSetChanged方法。(相当于刷新)大致思路就是这样。

然后提及一下RotateAnimation

Animation animation = new RotateAnimation(0, 90,holder.icon.getWidth() / 2, holder.icon.getHeight() / 2);animation.setDuration(200);animation.setFillAfter(true);holder.icon.startAnimation(animation);animation.setAnimationListener(new AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animation animation) {// TODO Auto-generated method stub}@Overridepublic void onAnimationEnd(Animation animation) {notifyDataSetChanged();}});
用法如下,构造方法是4参数的,代表旋转前角度、旋转后角度、旋转中心X,旋转中心Y。

setDuration设置时长,setFillAfter设置是否显示动画后的模样(默认是false)。设置好了,用startAnimation方法就可以开始动画了,并绑一个监听器。有一个注意点!!动画的话,和线程一样,是异步的!也就是说,你动画在放的时候,其他的代码块照样正常运行。这点要注意!

完整的代码:百度云链接

http://pan.baidu.com/s/1dDztv4d


0 0
原创粉丝点击