个人小作品系列,这次继续介绍自己曾经写的一些“小玩意”,这次就介绍下自己初学安卓时,写的一个简仿QQ吧。
里面都是一些基础知识,但是作为初学者来说,还是可以学到很多东西的。
由于这个涉及到的知识很散,就按照界面一个个说,主要就是一些安卓基础,要是你能耐心看下去的话,肯定都能做到。好啦,开始吧。
目录
1.欢迎界面(handler、Timer的使用等)
2.登录界面(属性动画、editText的清除效果、popupwindow的使用、Gif图片的显示等)
3.注册界面(短信功能的使用、Listview、组件间通信)
4.主界面(fragment的使用、自定义dialog、ExpandLIstView的使用)
5.主界面侧拉栏(自定义HorizontalScroView,动画的高级用法)
6.消息电话按钮切换效果(drawable的使用)
7.自定义Toast
8.特殊图片.9.png图片的使用方法与场景
正文
1.欢迎界面
我最终实现的是这个样子,截的QQ欢迎界面原图,然后用拙劣的PS技术签了个名!(现在感觉有点尬,不过记得当时还是觉得挺有意思的,哈哈),这个界面在持续3秒后,便会自动跳转到登录界面。
放图:
实现方式:
使用单独的一个activity,例如我这里为SplashActivity,然后修改程序的入口为SplashActivity
修改程序入口的方法为,在程序入口的activity下面加上下面这段代码,最终这个activity的申明是这个样子
<activity
android:name=".Splashactivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
需要注意的是一个应用程序中,只能有一个activity被申明为程序入口,我想这个应该很容易理解,我就不废话啦。
那么怎么实现界面停留3秒,跳转到登录界面的功能呢?这个实现方式有很多种,但是大致思路都是差不多的,可以handler,也可以用定时器(Timer)。我这里使用的第一种方法,相关代码也很简单,调用postDelayed()方法,根据我们要实现的需求这里使用两个参数的重载方法,第一个参数为实现了Runnable接口的对象,第二个参数为时间延迟,第一个对象中,由于Runnable为一个接口,便需要实现该接口下的run方法,在run方法里的代码,将在第二个参数设定的时间延迟后执行。相关代码如下
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Intent intent = new Intent(Splashactivity.this, QQ.class);
startActivity(intent);
Splashactivity.this.finish();
}
}, 3000);
不过既然是作为学习,我们也来学习下Timer类的使用。我当时这里为什么不用Timer实现也是有原因的,Timer是定时器,既然叫做定时器,那么这个东东实现的效果,是每隔一段时间做一些事情,但是我这里的需要是隔一段时间做一遍相应的事件即可,并不需要做很多遍,不过为什么我说Timer类也可以呢?因为timer既然定时了,肯定是可以取消的,我们只需要在事件执行一遍之后,取消该定时器即可,相关代码如下。
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
try {
Intent intent = new Intent(Splashactivity.this, QQ.class);
startActivity(intent);
Splashactivity.this.finish();
} catch (IOException e) {
e.printStackTrace();
}
}
};
timer.schedule(task,0,10000);
当然不要忘了,及时取消定时器哦,在Activity的onStop方法里执行 timer.cancel();
2.登录界面
不过对现在来说,这个界面已经不知道是QQ多少个版本之前的登录界面了,简单的布局就不介绍了,可以在源码里查看
说下这个界面需要注意的地方
(1)界面初次进入,有一个动画效果,gif图里可能看不太清,主要是,登录按钮反复掉下弹起,同时用户名密码输入框整体向上移动,类似浮起的效果,这两段动画同时开始同时停止。
(2)用户名密码输入框,在输如数据后有一个清除的小图标,点击小图标,会清空输入框的内容
(3)用户名输入指定的用户名,头像会显示指定的头像,例如我这里效果是输入942845204,头像自动更改为其它头像
(4)用户名输入框最右侧有一个下拉按钮,单机会弹出历史输入信息,点击历史信息条目,自动在用户名密码框中填入对应的信息
(5)登录的加载效果,按钮点击的变色效果,以及声音效果(,,假装可以听到 声音)
当然这些都是完全按照QQ来模仿的。我们按顺序来一个个实现
1.布局的动画效果,这里使用属性动画实现
首先是按钮的掉下弹起效果,使用属性动画ObjectAnimator,直接放代码吧
// 掉下弹起效果
ObjectAnimator yObjectAnimator = ObjectAnimator.ofFloat(btn1, "y", 0, DpUtils.dip2px(QQ.this,260));
yObjectAnimator.setDuration(2200);
yObjectAnimator.setInterpolator(new BounceInterpolator());
yObjectAnimator.setRepeatCount(0);
yObjectAnimator.start();
这里btn1就是我的登录按钮对象,可以看到核心方法就是ofFloat这个方法,参数解释如下
参数一:要执行动画的Object对象
参数二:执行动画的类型,传入字符串,这个有很多值,例如我这里“y”就表示竖直方向的移动动画,若为“alpha”则为透明度变化的动画,还有一些其他值,就不列举了
参数三和参数四可以看做一组,这里我再这一组里写了两个值,分别代表动画起始y值(即0,表示屏幕最上方),动画结束y值(由于单位是px,这里用工具类转换一下,我这里根据上面控件的高度,设定为260dp)
setDuration方法用于设定动画执行的时间,单位是毫秒,我这里2200代表执行2.2秒
setInterpolator设置执行效果(或者称为加速值),什么意思呢,就是动画在执行的过程中,会有速度上的差异,例如,我可以动画开始时执行速度快,然后慢,然后再快,也可慢-快-慢这样来执行,这里我传入了一个BouncdInterpolartor对象,这个是安卓为我们封装好的一个对象,使用它我们可以直接实现反复掉下弹起的效果。
setRepeatCount设定重复次数,为0,表示只执行一次
最后调用start方法在需要执行的地方调用,开始动画。
2.用户名密码输入框,清除效果
这个效果,现在应该有很多可以直接使用的库了,但是其实自己动手做的话也很简单,自己做的东西有一个好处就是自己想怎么改怎么改,别人的可能因为思路不一样有很多问题,所以自己多动多想,核心代码如下
TextWatcher watcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
String textname = editText1.getText().toString();
if (textname.length() > 0 && editText1.isFocused()) {
imageView2.setVisibility(View.VISIBLE);
imageView2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
editText1.setText("");
imageView2.setVisibility(View.INVISIBLE);
}
});
} else {
imageView2.setVisibility(View.INVISIBLE);
}
if (textname.equals("942845204")) {
imageview1.setImageDrawable(getResources().getDrawable(R.drawable.image2));
} else {
imageview1.setImageDrawable(getResources().getDrawable(R.drawable.image1));
}
String textpassword = editText2.getText().toString();
if (textpassword.length() > 0 && editText2.isFocused()) {
imageView3.setVisibility(View.VISIBLE);
imageView3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
editText2.setText("");
imageView3.setVisibility(View.INVISIBLE);
}
});
} else {
imageView3.setVisibility(View.INVISIBLE);
}
}
@Override
public void beforeTextChanged(CharS