Android---程序锁(1)展示页面的搭建
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Android---程序锁(1)展示页面的搭建,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含8876字,纯文字阅读大概需要13分钟。
内容图文
![Android---程序锁(1)展示页面的搭建](/upload/InfoBanner/zyjiaocheng/1064/abfccf8bf98e4acc929b35b21f833f03.jpg)
一.写在前面的话
在日常使用手机的过程中,我们经常希望有这样一个功能:可以对我们的某一个应用加锁,进入的时候需要输入密码验证身份,然后才可以进入主界面,这就是一个程序锁的功能。其实这种功能并不难实现,正在在我最近敲的一个大的Demo里有这一块的内容,所以决定记录一下实现的方式。
二.界面显示逻辑
2.1界面效果图
2.2layout布局文件
这里我们将“未加锁”和“已加锁”两个模块的ListView写在同一个布局文件中,用android:visibility=”“ 属性结合上方按钮的选中来决定下方是显示哪一个ListView
布局文件代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:orientation="horizontal">
<Button
android:id="@+id/bt_unlock"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/tab_left_pressed"android:text="未加锁"android:textColor="#fff"android:textSize="18sp"/>
<Button
android:id="@+id/bt_lock"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/tab_right_default"android:text="已加锁"android:textColor="#fff"android:textSize="18sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_unlock"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical">
<TextView
android:id="@+id/tv_unlock"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="未加锁应用"/>
<ListView
android:id="@+id/lv_unlock"android:layout_width="match_parent"android:layout_height="match_parent">
</ListView>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_lock"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:visibility="gone">
<TextView
android:id="@+id/tv_lock"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="未加锁应用"/>
<ListView
android:id="@+id/lv_lock"android:layout_width="match_parent"android:layout_height="match_parent">
</ListView>
</LinearLayout>
</LinearLayout>
注意到@+id/ll_lock android:visibility=”gone”,也就是通过对这两个属性的改变来控制下方的ListView到底显示的是哪一个。
2.3ListView的数据来源
有了ListView我们自然就会想到,LIstView始终需要两个部分,数据源和数据适配器,也就是Adapter。首先我记录一下展示数据的来源。
//区分已加锁应用和未加锁的应用
private
void
initData() {
new Thread(new Runnable() {
@Overridepublicvoidrun() {
//1.获取手机中所有的应用
mAppInfoList = appInfoProvider.getAppInfoList(getApplicationContext());
//2.区分已加锁应用和未加锁应用
mLockList = new ArrayList<AppInfo>();
mUnlockList = new ArrayList<AppInfo>();
//3.获取数据库中已加锁应用包名的集合
mDao = appLockDao.getInstance(getApplicationContext());
List<String> lockPackageList = mDao.findAll();
for (AppInfo appInfo : mAppInfoList) {
//4.如果循环到的应用的包名在数据库中,说明是已经加锁了的应用if (lockPackageList.contains(appInfo.getPackageName())) {
mLockList.add(appInfo);
} else {
mUnlockList.add(appInfo);
}
}
//5.告知主线程,数据准备好了,可以使用了 消息机制
mHandler.sendEmptyMessage(0);
}
}).start();
}
其中:appInfoProvider.getAppInfoList(getApplicationContext());
mDao = appLockDao.getInstance(getApplicationContext());
List lockPackageList = mDao.findAll();
这三个是我已经封装好的方法,分别用于拿到手机中所有的应用;拿到岁数据库增删改查的对象;拿到目前数据库中已经有的数据。
这个意思就是说,我将已经加锁的应用放到数据库中,然后将已经加锁和未加锁的应用分别放到两个集合中:mLockList,mUnlockList。由于拿数据这个操作可能耗时,所以我们将这个方法放到线程中去执行。最后在利用消息机制通知主线程,数据已准备好。
2.4Adapter的设置
由于我们将两个ListVIew都写在同一个布局里,所以我们也用一个Adapter同时去配置两个LIstView,只是加上一个private boolean isLock; 这个标记,来区分当前是配置哪一个ListView。
class myAdapter extends BaseAdapter {
privateboolean isLock;
//用于区分已加锁和未加锁应用的标识 重写的构造方法publicmyAdapter(boolean isLock) {
this.isLock = isLock;
}
@OverridepublicintgetCount() {
if (isLock) {
tv_lock.setText("已加锁应用:" + mLockList.size());
return mLockList.size();
} else {
tv_unlock.setText("未加锁应用:" + mUnlockList.size());
return mUnlockList.size();
}
}
@Overridepublic AppInfo getItem(int position) {
if (isLock) {
return mLockList.get(position);
} else {
return mUnlockList.get(position);
}
}
@OverridepubliclonggetItemId(int position) {
return position;
}
@Overridepublic View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = View.inflate(getApplicationContext(), R.layout.listview_islock_item, null);
holder.iv_icon = (ImageView) convertView.findViewById(R.id.iv_icon);
holder.iv_lock = (ImageView) convertView.findViewById(R.id.iv_lock);
holder.tv_name = (TextView) convertView.findViewById(R.id.tv_name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final AppInfo appinfo = getItem(position);
holder.iv_icon.setBackgroundDrawable(appinfo.getIcon());
holder.tv_name.setText(appinfo.getName());
if (isLock) {
holder.iv_lock.setBackgroundResource(R.drawable.lock);
} else {
holder.iv_lock.setBackgroundResource(R.drawable.unlock);
}
return convertView;
}
}
其中getView()方法中用了convertView和holderView来优化Listview,这已经是模板代码了。所以具体的HolderView就不贴出来了 。
==========================================
下面这个部分单独拎出来记录:
当我们在“未加锁”界面点击右边的小锁时候,我们希望达到这样的一种效果:我们点击的这一个条目产生一个动画效果,向右边滑出,然后消失,在“已加锁”界面显示出我们方才点击的哪一个条目
按照这种思路,我们首先弄一个执行动画的类:
/**
* 初始化平移动画,平移自身宽度
*
* @param
* @return
* @author zfy
* @created at 2016/6/26 10:56
*/
private
void
initAnimation() {
mTranslateAnimation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 1,
Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 0);
mTranslateAnimation.setDuration(500);
}
接下来我们在Adapter 的getView()方法中,监听holder.iv_lock这个图标 的点击事件:下面就是我一开始犯错误的地方了:
final View finalConvertView = convertView;
holder.iv_lock.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View v) {
//添加动画效果
finalConvertView.startAnimation(mTranslateAnimation);
if (isLock) {
//由已加锁------>未加锁//添加动画效果//1.已加锁的集合要删除一个,未加锁的几个要增加一个
mLockList.remove(appinfo);
mUnlockList.add(appinfo);
//2.从已加锁的数据库中删除一条数据
mDao.delete(appinfo.getPackageName());
//3.通知adapter刷新
mLockAdapter.notifyDataSetChanged();
} else {
//未加锁----->已加锁//1.未加锁的集合要删除一个,已加锁的几个要增加一个
mLockList.add(appinfo);
mUnlockList.remove(appinfo);
//2.从已加锁的数据库中删除一条数据
mDao.insert(appinfo.getPackageName());
//3.通知adapter刷新
mUnlockAdapter.notifyDataSetChanged();
}
一切都是这么的水到渠成,点击加锁按钮–>开启动画–>从未加锁集合中删除–>添加到已加锁集合中–>添加到数据库–>通知adapter刷新。
但是我忽略了一个问题,当我执行平移动画的时候(500ms),下面对集合的操作,更新Adapter的操作就已经在执行了,并且已经执行完了。所以最终实现的动画效果是,我点了一个条目,但是发生平移动画的却是下一个条目。这一点困惑了很久!所以我在这里对动画做了一个监听:当动画执行完了,才接着行对集合,数据库,和adapter刷新的操作!!
final View finalConvertView = convertView;
holder.iv_lock.setOnClickListener(new View.OnClickListener() {
@OverridepublicvoidonClick(View v) {
//添加动画效果
finalConvertView.startAnimation(mTranslateAnimation);
//对动画执行的效果做监听,要监听到动画执行完成之后,再去移除集合中数据,操作数据库,刷新界面
mTranslateAnimation.setAnimationListener(new Animation.AnimationListener() {
@OverridepublicvoidonAnimationStart(Animation animation) {
}
@Override//动画结束后回调方法publicvoidonAnimationEnd(Animation animation) {
if (isLock) {
//由已加锁------>未加锁//添加动画效果//1.已加锁的集合要删除一个,未加锁的几个要增加一个
mLockList.remove(appinfo);
mUnlockList.add(appinfo);
//2.从已加锁的数据库中删除一条数据
mDao.delete(appinfo.getPackageName());
//3.通知adapter刷新
mLockAdapter.notifyDataSetChanged();
} else {
//未加锁----->已加锁//1.未加锁的集合要删除一个,已加锁的几个要增加一个
mLockList.add(appinfo);
mUnlockList.remove(appinfo);
//2.从已加锁的数据库中删除一条数据
mDao.insert(appinfo.getPackageName());
//3.通知adapter刷新
mUnlockAdapter.notifyDataSetChanged();
}
}
@OverridepublicvoidonAnimationRepeat(Animation animation) {
}
});
}
});
最终写成这个样子,就完全没有问题了。
2.5对最上方两个按钮的处理
bt_unlock.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//1.已加锁列表隐藏,未加锁列表显示
ll_lock.setVisibility(View.GONE);
ll_unlock.setVisibility(View.VISIBLE);
//2.按钮颜色切换
bt_lock.setBackgroundResource(R.drawable.tab_right_default);
bt_unlock.setBackgroundResource(R.drawable.tab_left_pressed);
}
});
bt_lock.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//1.已加锁列表显示,未加锁列表隐藏
ll_lock.setVisibility(View.VISIBLE);
ll_unlock.setVisibility(View.GONE);
//2.按钮颜色切换
bt_lock.setBackgroundResource(R.drawable.tab_right_pressed);
bt_unlock.setBackgroundResource(R.drawable.tab_left_default);
}
});
比较简单,就不作说明了。
2.6分别设置Adapter
private Handler mHandler = new Handler() {
@OverridepublicvoidhandleMessage(Message msg) {
//接收到消息,填充已加锁和未加锁的数据适配器
mLockAdapter = new myAdapter(true);
lv_lock.setAdapter(mLockAdapter);
mUnlockAdapter = new myAdapter(false);
lv_unlock.setAdapter(mUnlockAdapter);
}
};
这也是常规写法,不做说明
三. 后记
到这里就已经可以实现程序锁的界面展示效果了,但是具体的业务逻辑还没有处理, 只是一个空架子。
由于明天还有《数字信号处理》的抽考,今天还要复习,所以业务逻辑这一块,留到考试考完再记录。
PS: 《数字信号处理》 这门课也是够了。整本书的傅里叶变换,离散傅里叶变换,快速傅里叶变化,Z变换,逆Z变换……TM的 ~
上次写的Widget那片文章,不知道为什么,居然一晚上有2000多人浏览。。是我的 错觉吗?我这个渣渣的技术博客一篇文章居然访问量这么高。 还是最近很多人在学这一块的实现?
不管为什么,这也让我更加坚定,坚持写技术博客的决心!
原文:http://blog.csdn.net/sinat_33661267/article/details/51773506
内容总结
以上是互联网集市为您收集整理的Android---程序锁(1)展示页面的搭建全部内容,希望文章能够帮你解决Android---程序锁(1)展示页面的搭建所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。