这是手机QQ2013官方版的登录界面:

这个是我自己做出来的 QQ登录界面:

当然与官方版相比还是有很大的差距,不过对于学习安卓控件的使用已经足够了。

  为实现上述界面,需要有几个关键的知识点需要学习:

一、实现圆角的效果——学会使用描述背景的drawable/中的 xml文件

  需要在drawable文件夹中创建xml文件,文件的父控件类型为shape,在shape父控件中,有<solid/>  <corners/> <stroke/> <padding/> 等属性,分别处理背景的填充颜色、边角的曲率、边框线的宽度和颜色、上下左右内边框(即背景超出使用改背景的空间的宽度)

例如,若想实现一个圆角的ImageButton,可以创建一个 fillet_shape.xml文件

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" ><solid android:color="#ffffff"/><corners android:radius="10px"/><padding android:left="3dip" android:top="3dip" android:right="3dip" android:bottom="3dip"/></shape>

然后在Activity类中用ImageButton的实例设置setBackgroundResource(); 或者在xml布局文件中在配置控件属性使用  android:background="@drawable/fillet_shape"
注意这里在配置好背景之后,在为ImageView设置显示的图片时,只能使用setImageResource()而不能使用setBackgroundResource();

学会这点很重要,后面就可以举一反三,本例中使用该方法为 EditText设置了边框,为ListView的每一个Item设置了边框,为按钮设置了圆角背景。就不再特殊说明

二、RelativeLayout中控件的布局问题

  不同控件之间是可以覆盖的,注意在布局文件中后配置的空间可以覆盖掉之前配置的空间,所以本例在布局文件中让ListView控件放在了最后,另外如果想要一个控件暂时消失

可以使用setVisibility(View.GONE);的方法,这样改控件消失以后被覆盖的空间就可以正常使用了。另外本例在EditText中添加按钮并没有自定义EditText,而是直接通过布局文件的描述将联系人游标(小箭头)嵌在了Edittext中。注意这里一般不使用View.INVISIBLE,这样控件并未消失

三、notifyDataSetChanged方法是BaseAdapter的方法,所以可以在构造的适配器内部或者创建的适配器对象使用。

四、并不是只有Button可以设置OnClickListener  实际上很多常见的空间都可以使用,如EditText或者TextView ,这个应该是属于View的抽象方法

五、ListView如何调整每一个Item边框的宽度并且避免Item之间的分割线颜色太深?

方法就是上面介绍的自定义drawable/ 中xml文件,来配置边和背景属性,另外在配置ListView控件的属性时 设置android:divider="#aaaaaa" android:dividerHeight="0px"  这样可以是ListItem的边框做出上图所示的效果。

六、怎样解决ListView中添加Button之后就不响应单击事件的问题?

  原因是Button抢夺了焦点,最简单的解决办法是:在自定义的每一个ListItem的布局文件中在根标签的属性中添加上 android:descendantFocusability="blocksDescendants" 即拒绝ListItem中的子控件获得焦点

七、怎样实现在点击某个控件以外的屏幕区域就使该控件消失的效果?本例中实现在点击ListView以外的区域就会使ListView消失的效果。

方法是覆写MainActivity的onTouchEvent()方法,根据点击的坐标(x,y)与目标控件通过getLocation获得的控件左上角坐标,再结合目标控件的宽和高,判断点击的点是否在控件内,进而决定对该控件执行怎样的操作。

例子:

@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubif(event.getAction()==MotionEvent.ACTION_DOWN && isVisible){int[] location=new int[2];//调用getLocationInWindow方法获得某一控件在窗口中左上角的横纵坐标
            loginList.getLocationInWindow(location);//获得在屏幕上点击的点的坐标int x=(int)event.getX();  int y=(int)event.getY();if(x<location[0]|| x>location[0]+loginList.getWidth() ||y<location[1]||y>location[1]+loginList.getHeight()){isIndicatorUp=false;isVisible=false;listIndicatorButton.setBackgroundResource(R.drawable.indicator_down);loginList.setVisibility(View.GONE);   //让ListView列表消失,并且让游标向下指!
                }}return super.onTouchEvent(event);}

以上就是我在写程序的过程中遇到的一些难题,天有些晚了,直接上所有的代码吧。。

首先布局文件activity_main.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"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity"android:background="#dde1ee" ><ImageView android:id="@+id/myImage"android:layout_width="70dip"android:layout_height="70dip"android:layout_marginTop="65dip"android:layout_centerHorizontal="true"android:background="@drawable/fillet_shape"/><EditText android:id="@+id/qqNum"android:layout_width="match_parent"android:layout_height="40dip"android:layout_marginLeft="30dip"android:layout_marginRight="30dip"android:layout_marginTop="15dip"android:paddingLeft="50dip"android:layout_below="@id/myImage"android:inputType="number"android:background="@drawable/qqnum_edit"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="账号"android:textSize="8pt"android:textColor="@android:color/darker_gray"android:layout_alignLeft="@id/qqNum"android:layout_alignTop="@id/qqNum"android:layout_marginTop="9dip"android:layout_marginLeft="3dip"/><EditText android:id="@+id/qqPassword"android:layout_width="match_parent"android:layout_height="40dip"android:paddingLeft="50dip"android:layout_marginLeft="30dip"android:layout_marginRight="30dip"android:layout_below="@id/qqNum"android:background="@drawable/qqnum_edit"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="密码"android:textSize="8pt"android:textColor="@android:color/darker_gray"android:layout_alignLeft="@id/qqPassword"android:layout_alignTop="@id/qqPassword"android:layout_marginTop="9dip"android:layout_marginLeft="3dip"/><ImageButtonandroid:id="@+id/qqListIndicator"android:layout_width="22dip"android:layout_height="20dip"android:layout_marginBottom="8dip"android:layout_marginRight="3dip"android:layout_alignBottom="@+id/qqNum"android:layout_alignRight="@+id/qqNum"android:background="@drawable/indicator_down" /><ImageButton android:id="@+id/delete_button_edit"android:layout_width="18dip"android:layout_height="18dip"android:layout_marginBottom="8dip"android:layout_marginRight="3dip"android:layout_alignBottom="@+id/qqNum"android:layout_toLeftOf="@id/qqListIndicator"android:background="@drawable/delete_button_edit"android:visibility="gone"/><Button android:id="@+id/qqLoginButton"android:layout_width="match_parent"android:layout_height="35dip"android:layout_below="@id/qqPassword"android:layout_alignLeft="@id/qqNum"android:layout_alignRight="@id/qqNum"android:layout_marginTop="20dip"android:background="@drawable/login_button_back"android:text="登录"android:textColor="@android:color/white"/><TextView android:id="@+id/fetchPassword"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentLeft="true"android:layout_below="@id/qqLoginButton"android:layout_marginLeft="45dip"android:text="找回密码"android:textSize="7pt"android:textColor="#333355"android:gravity="bottom"/><TextView android:id="@+id/registQQ"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/qqLoginButton"android:layout_alignParentBottom="true"android:layout_alignParentRight="true"android:layout_marginRight="45dip"android:layout_marginTop="5dip"android:text="注册账号"android:textSize="7pt"android:textColor="#333355"android:gravity="bottom"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/qqLoginButton"android:text="|"android:textSize="7pt"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:gravity="bottom"/><ListViewandroid:id="@+id/loginQQList"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_above="@id/registQQ"android:layout_alignLeft="@id/qqNum"android:layout_alignRight="@id/qqNum"android:layout_below="@id/qqNum"android:focusable="true"android:focusableInTouchMode="true"android:visibility="gone"android:divider="#aaaaaa"android:dividerHeight="0px"/></RelativeLayout>

listItem的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="35dip"android:orientation="horizontal"android:background="@drawable/list_item_border"android:descendantFocusability="blocksDescendants" ><ImageView android:id="@+id/login_userPhoto"android:layout_width="match_parent"android:layout_weight="4.7"android:layout_height="30dip"android:background="@drawable/contact_1"android:layout_marginLeft="10dip"android:layout_marginTop="5dip"android:layout_marginRight="15dip"android:layout_marginBottom="5dip"/><TextViewandroid:id="@+id/login_userQQ"android:layout_width="match_parent"android:layout_height="30dip"android:layout_marginTop="5dip"android:layout_weight="2"android:gravity="center_vertical"android:text="1234567890"android:textSize="7pt" /><ImageButtonandroid:id="@+id/login_deleteButton"android:layout_width="match_parent"android:layout_weight="5.8"android:layout_height="14dip"android:layout_marginTop="11dip"android:layout_marginRight="3dip"android:focusable="true"android:focusableInTouchMode="true"android:background="@drawable/deletebutton" /></LinearLayout>

至于实现圆角等边框效果的xml布局文件就不再添加,上面第一条已经给出例子,可以根据需要的效果进行推广。

然后就是MainActivity文件,这里为了适配器类等够对Activity界面进行更改,将适配器类写成了MainActivity类的内部类,代码中有说明。另外相当一部分代码是为了实现一些细节性的东西,如EditText中游标的的方向变化,图片图案的变化,使用了一些常量。

package com.example.android_qq_login;import java.util.ArrayList;
import java.util.HashMap;
import com.qqlist.contactor.UserInfo;import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.*;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;public class MainActivity extends Activity {TextView textFetchPassWord=null,textRegister=null;Button loginButton=null;ImageButton  listIndicatorButton=null, deleteButtonOfEdit=null;ImageView currentUserImage=null;ListView loginList=null;EditText qqEdit=null, passwordEdit=null;private static boolean isVisible=false;         //ListView是否可见private static boolean isIndicatorUp=false;     //指示器的方向public static int currentSelectedPosition=-1;    //用于记录当前选择的ListView中的QQ联系人条目的ID,如果是-1表示没有选择任何QQ账户,注意在向//List中添加条目或者删除条目时都要实时更新该currentSelectedPosition
    String[] from={"userPhoto","userQQ","deletButton"};int[] to={R.id.login_userPhoto,R.id.login_userQQ,R.id.login_deleteButton};ArrayList<HashMap<String,Object>> list=null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textFetchPassWord=(TextView)findViewById(R.id.fetchPassword);textRegister=(TextView)findViewById(R.id.registQQ);loginButton=(Button)findViewById(R.id.qqLoginButton);listIndicatorButton=(ImageButton)findViewById(R.id.qqListIndicator);loginList=(ListView)findViewById(R.id.loginQQList);list=new ArrayList<HashMap<String,Object>>();currentUserImage=(ImageView)findViewById(R.id.myImage);qqEdit=(EditText)findViewById(R.id.qqNum);passwordEdit=(EditText)findViewById(R.id.qqPassword);deleteButtonOfEdit=(ImageButton)findViewById(R.id.delete_button_edit);qqEdit.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(qqEdit.getText().toString().equals("")==false){deleteButtonOfEdit.setVisibility(View.VISIBLE);}}});deleteButtonOfEdit.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub
                currentUserImage.setImageResource(R.drawable.qqmain);qqEdit.setText("");currentSelectedPosition=-1;deleteButtonOfEdit.setVisibility(View.GONE);}});UserInfo user1=new UserInfo(R.drawable.contact_0,"1234567",R.drawable.deletebutton);UserInfo user2=new UserInfo(R.drawable.contact_1,"10023455",R.drawable.deletebutton);addUser(user1);addUser(user2);//设置当前显示的被选中的账户的头像if(currentSelectedPosition==-1){currentUserImage.setImageResource(R.drawable.qqmain);qqEdit.setText("");}else{currentUserImage.setImageResource((Integer)list.get(currentSelectedPosition).get(from[0]));qqEdit.setText((String)list.get(currentSelectedPosition).get(from[1]));}MyLoginListAdapter adapter=new MyLoginListAdapter(this, list, R.layout.layout_list_item, from, to);loginList.setAdapter(adapter);loginList.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {// TODO Auto-generated method stubcurrentUserImage.setImageResource((Integer)list.get(arg2).get(from[0]));qqEdit.setText((String)list.get(arg2).get(from[1]));currentSelectedPosition=arg2;//相应完点击后List就消失,指示箭头反向!
                loginList.setVisibility(View.GONE);listIndicatorButton.setBackgroundResource(R.drawable.indicator_down);System.out.println("---------Selected!!");}});listIndicatorButton.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(isIndicatorUp){isIndicatorUp=false;isVisible=false;listIndicatorButton.setBackgroundResource(R.drawable.indicator_down);loginList.setVisibility(View.GONE);   //让ListView列表消失
                    }else{isIndicatorUp=true;isVisible=true;listIndicatorButton.setBackgroundResource(R.drawable.indicator_up);loginList.setVisibility(View.VISIBLE);}}});}//继承onTouchEvent方法,用于实现点击控件之外的部分使控件消失的功能private void addUser(UserInfo user){HashMap<String,Object> map=new HashMap<String,Object>();map.put(from[0], user.userPhoto);map.put(from[1], user.userQQ);map.put(from[2], user.deleteButtonRes);list.add(map);}@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubif(event.getAction()==MotionEvent.ACTION_DOWN && isVisible){int[] location=new int[2];//调用getLocationInWindow方法获得某一控件在窗口中左上角的横纵坐标
            loginList.getLocationInWindow(location);//获得在屏幕上点击的点的坐标int x=(int)event.getX();  int y=(int)event.getY();if(x<location[0]|| x>location[0]+loginList.getWidth() ||y<location[1]||y>location[1]+loginList.getHeight()){isIndicatorUp=false;isVisible=false;listIndicatorButton.setBackgroundResource(R.drawable.indicator_down);loginList.setVisibility(View.GONE);   //让ListView列表消失,并且让游标向下指!
                }}return super.onTouchEvent(event);}/*** 为了便于在适配器中修改登录界面的Activity,这里把适配器作为* MainActivity的内部类,避免了使用Handler,简化代码* @author DragonGN**/public class MyLoginListAdapter extends BaseAdapter{protected Context context;protected ArrayList<HashMap<String,Object>> list;protected int itemLayout;protected String[] from;protected int[] to;public MyLoginListAdapter(Context context,ArrayList<HashMap<String, Object>> list, int itemLayout,String[] from, int[] to) {super();this.context = context;this.list = list;this.itemLayout = itemLayout;this.from = from;this.to = to;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn list.size();}@Overridepublic Object getItem(int arg0) {// TODO Auto-generated method stubreturn null;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}class ViewHolder{public ImageView userPhoto;public TextView userQQ;public ImageButton deleteButton;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubViewHolder holder=null;/*currentPosition=position;    不能使用currentPosition,因为每绘制完一个Item就会更新currentPosition这样得到的currentPosition将始终是最后一个Item的position        */if(convertView==null){convertView=LayoutInflater.from(context).inflate(itemLayout, null);holder=new ViewHolder();holder.userPhoto=(ImageView)convertView.findViewById(to[0]);holder.userQQ=(TextView)convertView.findViewById(to[1]);holder.deleteButton=(ImageButton)convertView.findViewById(to[2]);convertView.setTag(holder);}else{holder=(ViewHolder)convertView.getTag();}holder.userPhoto.setBackgroundResource((Integer)list.get(position).get(from[0]));holder.userQQ.setText((String)list.get(position).get(from[1]));holder.deleteButton.setBackgroundResource((Integer)list.get(position).get(from[2]));holder.deleteButton.setOnClickListener(new ListOnClickListener(position));return convertView;}class ListOnClickListener implements OnClickListener{private int position;public ListOnClickListener(int position) {super();this.position = position;}@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stub
                list.remove(position);//如果删除的就是当前显示的账号,那么将主界面当前显示的头像设置回初始头像if(position==currentSelectedPosition){currentUserImage.setImageResource(R.drawable.qqmain);qqEdit.setText("");currentSelectedPosition=-1;}else if(position<currentSelectedPosition){currentSelectedPosition--;    //这里小于当前选择的position时需要进行减1操作
                }listIndicatorButton.setBackgroundResource(R.drawable.indicator_down);loginList.setVisibility(View.GONE);   //让ListView列表消失,并且让游标向下指!
                MyLoginListAdapter.this.notifyDataSetChanged();    }}}}

另外再多附几张效果图:

  

转载地址:http://www.cnblogs.com/carlos-vic/p/Carlos_V_Android_11.html?utm_source=tuicool&utm_medium=referral

Android开发系列(十一) QQ登陆界面——Android控件使用实例相关推荐

  1. android禁止下拉刷新,Android开发之无痕过渡下拉刷新控件的实现思路详解

    相信大家已经对下拉刷新熟悉得不能再熟悉了,市面上的下拉刷新琳琅满目,然而有很多在我看来略有缺陷,接下来我将说明一下存在的缺陷问题,然后提供一种思路来解决这一缺陷,废话不多说!往下看嘞! 1.市面一些下 ...

  2. Android开发技巧——定制仿微信图片裁剪控件

    拍照--裁剪,或者是选择图片--裁剪,是我们设置头像或上传图片时经常需要的一组操作.上篇讲了Camera的使用,这篇讲一下我对图片裁剪的实现. 背景 下面的需求都来自产品. 裁剪图片要像微信那样,拖动 ...

  3. Android自定义控件系列(1):选项控件

    一.控件效果展示 二.控件类:OptionsItemView.java /*** 选项Item* * @author : ZGS* Created on 2021/11/16**/ public cl ...

  4. Android studio新手:实现最新版QQ登陆界面

    最新版QQ登陆界面如下: 代码实现效果如下: activity_main.xml代码如下: <?xml version="1.0" encoding="utf-8& ...

  5. android qq登陆界面代码下载,【Android Demo】QQ登陆界面(一)

    之前以及实现了QQV.0.8.4115的登陆界面,现在来总结一下,并且回顾一下用到过的东西. 先上图: [原图] QQLogin_0.jpg [图一] QQLogin_1.PNG [图二] QQLog ...

  6. android模仿qq登录界面,初识Android二之小试牛刀模仿实现qq登陆界面

    初识Android二之小试牛刀模仿实现qq登陆界面.俗话说得好,老师踢开门,修行在自己.勉勉强强学完生命周期,然后悠悠闲闲听了两节课后,老师就布置了一个登陆界面的实现,于是,磕磕绊绊的修行之路开始了. ...

  7. android布局基础及范例:QQ登陆界面设计

    使用android手机的用户想必都有android手机QQ客户端吧,我们是不是觉得QQ登陆界面非常漂亮美观而且具有亲和力?我们是不是也想作出像 QQ那样美观的界面?有的人肯定会问,做UI那不是美工人员 ...

  8. 最新网易微专业 Android开发系列

    目录 ├─1.Android应用界面开发 │  ├─001 Android开发简介.flv │  ├─002 开始第一个应用.flv │  ├─003 Activity你必须知道的那些事(上).flv ...

  9. Android开发系列7——icon图标和开机启动页

    前言   Android开发App过程中,需要一个独特吸引眼球的应用icon,以及标新的Launch页面用于简明的介绍.为了适配各种 手机的尺寸和手机屏幕分辩率,需要同一张图片制作多种尺寸用于兼容各种 ...

  10. Android 简单的账号密码登陆界面(IO流)

    Android 简单的账号密码登陆界面(IO流) 用到了map<String,String> .IO流等. MainActivity代码如下: package com.xh.tx.file ...

最新文章

  1. android读取xml 字符串,Android 读取本地Xml文件,并转换成String
  2. umi搭建react+antd项目(三)Mock 数据--模拟数据
  3. 11.1 问题描述及流程-机器学习笔记-斯坦福吴恩达教授
  4. html(3)标签(2)
  5. PAT (Basic Level) 1095 解码PAT准考证(模拟+stl,好题)
  6. Java常见GC算法_垃圾收集器及内存分配_G1垃圾收集器
  7. C++中关于隐藏的理解
  8. c语言第六次上机作业,C语言第五次上机作业参考答案
  9. 区块链教程(五):合约编写实战实例
  10. H264所采用的指数格伦布熵编码算法原理及应用
  11. 24秒篮球计时器mulisim12.0_奥尼尔力量有多恐怖?325磅体重把整个篮球架子拦腰折断...
  12. three.js 求两个vector3 的夹角_初中数学:动点问题-阿氏圆最值模型(2),求PD-1/2PC的最大值...
  13. java课设电子门禁_中控门禁pullSdk Java demo 中控智慧门禁系统 - 下载 - 搜珍网
  14. 变压器绕组降低邻近效应_高功率UPS性能提升,规格/重量显著降低
  15. 怎么做应力应变曲线_做了这么多年材料,这些力学性能测试你做对了吗?
  16. Dubbo 的心跳设计,值得学习!
  17. 哲学家就餐问题 C语言实现
  18. 通信原理电子版_2021届通信工程专业保研经历分享+个人经验总结
  19. 用给定的key对字符串进行sha256加密-postman预处理
  20. 2021基于vscode以及jlink调试esp32最新

热门文章

  1. chrome插件Adblock Plus拓展程序
  2. Python3.WRF的投影转换
  3. 汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码
  4. 17万字 | 2021密码应用技术白皮书(附下载)
  5. 优化算法学习(LM算法)
  6. 周报、月报有多折磨人?万能报表模板建议收藏!(附模板)
  7. 2022上海Java工资收入概览
  8. solidworks电气元件3d库_丨软件丨如何提高电气配线的生产效率?
  9. 入门必备-经典的分子动力学软件LAMMPS简版手册
  10. MATLAB实现DES算法子密钥生成