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

一个简易的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() {

			@Override
			public 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方法

先上代码

@Override
	public 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() {

					@Override
					public void onAnimationStart(Animation animation) {
						// TODO Auto-generated method stub

					}

					@Override
					public void onAnimationRepeat(Animation animation) {
						// TODO Auto-generated method stub

					}

					@Override
					public void onAnimationEnd(Animation animation) {
						notifyDataSetChanged();
					}
				});
			}
		} else {
			if ((iconIndex == position) && (iconFlag2 == false)) {
				holder.description.setVisibility(View.VISIBLE);
			}
		}
		holder.icon.setOnClickListener(new OnClickListener() {

			@Override
			public 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() {

					@Override
					public void onAnimationStart(Animation animation) {
						// TODO Auto-generated method stub

					}

					@Override
					public void onAnimationRepeat(Animation animation) {
						// TODO Auto-generated method stub

					}

					@Override
					public void onAnimationEnd(Animation animation) {
						notifyDataSetChanged();
					}
				});
用法如下,构造方法是4参数的,代表旋转前角度、旋转后角度、旋转中心X,旋转中心Y。

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

完整的代码:百度云链接

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值