在MapEdit页面的设计当中,为了让用户知道自己当前选择的设施是什么,要对ListView子项目做一个选中就变更背景的一个效果。如下图:
界面中可以看到,点击图标后,会出现一个橙色的高亮边框。事实上,这是通过改变底图背景而达到的效果。
首先声明,此方法并非我原创,也是从很多地方学来的,具体地址当时忘记存了,现在也找不到了,但还是要感谢一下原作者。
首先要在Drawable文件夹下,新建一个子项的底图背景,我把它取名叫:bg_normal.xml,作为正常情况下地底图背景
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 设置边框的大小和颜色 -->
<stroke
android:width="2dp"
android:color="@color/black" />
<!-- 设置图形内的颜色,此处为透明色 -->
<solid android:color="@android:color/transparent" />
<!-- 定义圆角弧度 圆的话就是半径 -->
<!--<corners android:radius="0dp"/>-->
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp" />
</shape>
然后再建一个用于点击后的背景效果,取名为:bg_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 设置边框的大小和颜色 -->
<stroke
android:width="2dp"
android:color="@color/orange" />
<!-- 设置图形内的颜色,此处为透明色 -->
<solid android:color="@android:color/transparent" />
<!-- 定义圆角弧度 圆的话就是半径 -->
<!--<corners android:radius="0dp"/>-->
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp" />
</shape>
可以发现,两个背景就颜色不同罢了。关键的来了,需要再新建一个selector.xml,这个文件就像一个容器,把两个背景装到一起,到时候设置到需要设置的地方(我们都知道,布局文件中,是不允许同一个元素设置两个不同背景的。)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/skill_image_bg_normal" android:state_activated="false"/>
<item android:drawable="@drawable/skill_image_bg_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/skill_image_bg_pressed" android:state_activated="true"/>
</selector>
最后呢,再把这个文件作为背景,设置到你要塞到ListView(不是ListView所在的布局文件,而是你想要塞到ListView里做内容的自定义的那个布局。)里的那个布局元素,作为背景。如下图:
当然啦,这样肯定还不够的,还必须在代码中做一点设置,在项目的onItemClick事件中,需要加入如下代码:
/**
* 技能点击事件
*
* @param parent
* @param view
* @param position
* @param id
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
skillListView.setItemChecked(position, true);
}
以上方法需要实现OnItemClickListener接口,这段我就不介绍了,可以自己去查看其他资料。然后呢,我们还要实现一个需求,就是修改里面道具的所剩个数,这个比较麻烦,需要在代码中做一些手脚。
/**
* 获取选中的Skill对象
*
* @param selectedItem
* @return
*/
private Skill getSelectedSkill(int selectedItem) {
Skill skill = skillAdapter.getItem(selectedItem);
return skill;
}
/**
* 更新列表中的数据
*
* @param skill
*/
private void updateList(Skill skill) {
int currentNum = skill.getNum();
if (currentNum == 0) {
ToastUtil.show("此设施已经用光了!");
} else {
skill.setNum(currentNum - 1);
skillAdapter.notifyDataSetChanged();
}
}
做一个简单解释,首先呢,我们要用ListView一定会有的一个适配器,我代码中的适配器就是skillAdapt,用这个适配器,获取到之前初始化装填入适配器的对象,当然啦,得根据一个selectedItem标记来获取指定的对象,这个selectedItem就是前面onItemClick方法里地position参数,那取到对应的对象了,只需要修改对象的参数就可以了,这个就比较简单了吧,第二个方法中最后一行代码的意思,可以理解为更新ListView中的内容,相当于刷新操作,本身就是Adapter这个类的一个方法。第二个方法中的针对Num的操作,直接影响的就是第一张截图中,道具的数量。
以上效果的实现,就是点击子项后,子项呈现橙色,然后再在需要地方调用updateList()方法,更新子项的内容(本例中的数量)。