程序锁功能
步骤:1、未加锁 a) 设计布局,初始化组件 b) 获取数据(开启子线程获取) c) 获取完毕,发送消息给主线程 d) 主线程接收到消息,为ListView设置适配器,更新界面数据 e) 设置条目点击事件,当被点击的时候,移除到集合外,添加到数据库中 f) 为每个移除的条目设置动画 2、加锁类似 |
技术点: 1、在未加锁,为每一个item设置一个点击事件, 当点击某个条目时,获取该条目信息,然后将其从未加锁List给移除掉,然后添加到加锁的List中去, 然后更新ListView界面内容 unLockedAdapter.notifyDataSetChanged(); lockedAdapter.notifyDataSetChanged();// 这句如果不加上,那么在已加锁列表不会添加上2、在哪获取加锁和未加锁应用的个数? 在getCount()方面里面,因为getCount()最清楚ListView要被展示多少个条目。 @Override public int getCount() { if (isAppUnlocked) {// 未加锁 if (unlockedAppInfos != null) { tv_app_unlocked_count.setText("未加锁应用:"+unlockedAppInfos.size()+"个"); //放这里最好,因为它最清楚ListView中有多少个条目 return unlockedAppInfos.size(); } } else {// 已加锁 if (lockedAppInfos != null) { tv_app_locked_count.setText("已加锁应用:"+lockedAppInfos.size()+"个"); //放这里最好,因为它最清楚ListView中有多少个条目 return lockedAppInfos.size(); } } return 0; }3、在未加锁界面,每次一点击一个条目,将该条目从未加锁集合中给移除,然后将其加入到数据库(保存加锁的应用的数据库),然后 notifyDataSetChanged(),更新ListView界面上的数据,加锁ListView和未加锁ListView都要更新,否则,不会同步数据。 4、播放动画,主要要等动画播放完毕,才能更新UI 1)播放xml定义的动画 a) 动画定义 <?xml version="1.0" encoding="utf-8"?>
<!-- 7、未加锁应用移到加锁应用对应的动画效果 -->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="100%"
android:toYDelta="0" >
</translate> b) 动画播放 // a)添加到加锁应用对应的动画
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.applock_add);
// 谁播放动画?当前被点击的item,也就是view
view.startAnimation(animation);2)子线程中更新UI快捷操作 runOnUiThread(new Thread() {}); |
程序锁核心代码:
|
结果: |
问题1:当退出,再次进来的时候,又恢复了原样,原因是存在内存,下次进来数据又丢失了。 解决:将数据存到数据库中,每次加载的时候,从数据库中获取数据,点击时添加和删除数据库中对应的记录。 |
问题2:播放动画时,有问题。 比如,未加锁应用移动应用到加锁中的动画,每次移除,都有下面的条目先移除,然后又回来了。 分析:由于播放动画是在主线程中单独开启一个新的子线程进行的播放,所以播放动画需要一定的时间。 当一个条目被移除时,而我们又复用了convertView,此动画还没有播放完毕,就会导致下一个条目播放这个动画,即被移除去,然后动画播放完毕,界面更新了,看似被移除的条目又被显示在界面上,这样看起来就是从右边移过来一样。 问题代码: // d)设置未加锁应用ListView中item的监听事件
lv_app_unlocked.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// 1、首先获取当前item的AppInfo信息
AppInfo appInfo = unlockedAppInfos.get(position); //添加到加锁应用对应的动画
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.applock_add);
// 谁播放动画?当前被点击的item,也就是view
view.startAnimation(animation);
// 2、 从unlockedAppInfos集合中移除该元素
unlockedAppInfos.remove(appInfo);
// 3、 从lockedAppInfos集合添加该元素
lockedAppInfos.add(appInfo);
// 4、并添加到加锁应用的数据库中去
appLockDao.add(appInfo.getAppPackageName());
// 4、更新界面
unLockedAdapter.notifyDataSetChanged();
lockedAdapter.notifyDataSetChanged();// 这句如果不加上,那么在已加锁列表不会添加上
}
});解决:我们知道,每一个操作系统,android,ios,wp,界面,都是一个死循环,内嵌一个消息机制,在不定时地等待消息的到来。 所以,我们要让动画有足够的时间播放完毕,然后才能更新ui的操作 解决后代码: // d)设置未加锁应用ListView中item的监听事件
lv_app_unlocked.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
final int position, long id) {
// a)添加到加锁应用对应的动画
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.applock_add);
// 谁播放动画?当前被点击的item,也就是view
view.startAnimation(animation);
// b)在子线程中睡过动画播放的时间,然后在更新UI
new Thread() {
@Override
public void run() {
// 不能主线程中睡眠,要开启子线程睡眠
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 睡了3秒后,然后在子线程中更新UI
runOnUiThread(new Thread() {
@Override
public void run() {
// 1、首先获取当前item的AppInfo信息
AppInfo appInfo = unlockedAppInfos.get(position);
// 2、 从unlockedAppInfos集合中移除该元素
unlockedAppInfos.remove(appInfo);
// 3、 从lockedAppInfos集合添加该元素
lockedAppInfos.add(appInfo);
// 4、并添加到加锁应用的数据库中去
appLockDao.add(appInfo.getAppPackageName());
// 4、更新界面
unLockedAdapter.notifyDataSetChanged();
lockedAdapter.notifyDataSetChanged();// 这句如果不加上,那么在已加锁列表不会添加上
}
});
}
}.start();
}
});
|