类似QQ登陆界面保存密码和账号下拉选择框

本界面的效果


界面效果


需要的知识

PopupWindon

ListView的内部响应事件

分析

通过对 PopupWindow 的了解,可知道他可以在你指定的 View 产生一个事件响应。他有多个构造函数,其中我们用到的构造函数为:

public PopupWindow (View contentView, int width, int height, boolean focusable)

其中 contentView 就是 PopupWindow 弹出的效果,而我们需要的就是这个。当有人点击一个 View 时,马上就有一个账号列表出现,一说到账号列表我相信你们马上就可以想到 ListView。对,我们用的就是 PopupWindow 和 ListView 来营造一个下拉选择框。并且在这个 ListView 中的每个 Item 都要相应外部点击。对于这个,我的解决方式为弄一个回调函数,进行实时处理。这些知识点已在前面 需要的知识 中列出,不懂的朋友可以先去看下。

步骤

ListView

通过上面的分析,我们的第一步,就是自定义一个 ListView ,也就是你需要账户列表的下拉风格。我做的下拉风格为,账号加可删除图案。XML 布局文件如下:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:descendantFocusability="blocksDescendants"
     android:background="#f9cef4ee"
     android:layout_height="wrap_content">

    <TextView
         android:id="@+id/muti_acount"
         android:text="多选"
         android:textSize="30sp"
         android:textColor="#101010"
         android:layout_weight="1"
         android:layout_width="0dp"
         android:layout_height="wrap_content" />

     <ImageView
         android:id="@+id/image_delete"
         android:src="@drawable/delete"
         android:layout_gravity="right|center"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content" />

 </LinearLayout>

当然这个布局文件随你自己,但是别忘了这句

android:descendantFocusability="blocksDescendants"

这其中的原因就是说当 ListView 中的 Item 出现时,Item 里面的子控件会得到焦点,而 Item 就没有焦点了,所以你点击 Item 无效。所以加上这句会覆盖子类控件而直接获得焦点

接下来继承 ArrayAdapter 编写我们自己的适配器。因为后面我会给出源码的,所以我们现在就只分析步骤。在这个适配器中我们需要将按键的点击事件传递给回调函数。然后再从回调函数生效的地方对按键的点击事件的具体事件给写出来。并且将点击的位置(Position)给传递到按键中,并在回调函数中得到这个 Position。这里传递 Position 我们用到的是 View 中的 setTag() 和 getTag() 方法。

Created with Raphaël 2.1.0 获取点击的时候的位置(position) 在回调函数中传递 Position 和 点击函数 onClick(View v) 确认无误 返回生成的 View yes

在 PopupWindow 中需要小心的就是在点击外部区域怎么把 PopupWindow 的提示框给消掉,这个问题也算是一个焦点的问题,由于在 所需的知识 中对于 PopupWindow 的讲解已经说了,就不说了。

点击事件

刚开始我尝试过在 PopupWindow 中进行点击事件的处理,发现弄不出来。然后我又尝试在 ListView 中进行点击事件的处理,又发现弄不出来。最后又尝试了几种方法都行不通,到最后上网搜到了在 ListView中进行回调函数,发现可行。具体实现模式见 所需的知识

在回调函数中我对传入的 View 进行了判断

如果点击的是 TextView,那么通过 getTag() 就把点击到的内容直接显示到账号的 EditText 中,然后再找出相应的密码。

如果点击的是 ImageView, 那么把该列的 Item 给删除掉。

用户信息存储

为了方便起见,在这里我用了 JSON 数组对多个账号和密码进行键值对存储(Key-Value),并用了 GSON 这个的库。

GSON 的用法

GSON 的功能很强大,直接可以将 Json 数据转换为对应的 对象。也可以将对象转换为相应的 Json 数据。
用法如下
先 new 一个Gson 对象

Gson gson = new Gson();

将单个 Json 数据转换为对象

Object object = gson.fromJson(jsonData, Object.class);

将 Json 数组转换为对象列表

List<Object> lists = gson.fromJson(jsonData, new TypeToken<List<Object>>(){}.getType());

将对象转换为 Json 数据和将对象列表转换为 Json 数组都一样,就参数不同。

String jsonData = gson.toJson(object);
String JsonData = gson.toJson(lists);

实施方案

情况一

当程序开始时,我会读取本地存文件,是否存储密码。如果没有,就什么都不做。如果有的话,将读到的 Json 数组转换为对象列表,再获得第一个对象,显示到界面上。

情况二

当用户输入了账号和密码时,我先进行账号和密码的验证,如果正确了,我再进行判断用户是否点击了保存密码。如果是,我就检查该账号是否和已经存在的账户相同,相同的话,进行存储,否则不进行存储。

情况三

当用户进行删除账号时,要进行实时的存储和通知适配器。

源码

https://github.com/whoma/ChooseAndStoge

结束

我发现遇到问题了,逐个分析,慢慢的就出来了。这是我第一次写博客,哪里写的不清楚,希望大家指出来。最后谢谢大家观看!

猜你喜欢

转载自blog.csdn.net/zwt520123/article/details/52727777
今日推荐