涉及技术
ListView使用、动画、自定义控件
第一步:ListView
ListView应该是每个学习Android的人都会学到的,所以我在这也就不仔细的说了,我只说一下设计的细节。
我们需要建立一个布局,用来显示在上一篇文章的PagerActivity中。xml不贴出了,可以看 这里。其实很简单,就是建立了一个ListView,设置分割距离和颜色并且去掉上下的阴影。ListView中每个item显示的布局可以看 这里,就只是一个TextView,用于显示标题。
关于数据我觉得我也不用多说,xml的处理也是Android学习的必学课程,为了练习xml的处理,所以我处理数据用了不同的方法,这里用的是SAX。数据提取出来之后给item加上点击事件:跳转到我们还未创建的HonorActivity。HonorActivity是用来显示每个荣誉的详细信息,也就是三个TextView,很简单,代码和布局可以看 这里和 这里。代码大概如下:
honorsListView = (ListView) honors.findViewById(R.id.honors_list);
honorsListView.setAdapter(new ArrayAdapter<String>(this, R.layout.honors_item, honorsListData()));
honorsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,final int position, long id) {
Intent toHonor = new Intent(context, HonorActivity.class);
toHonor.putExtra("id", position + 1);
startActivity(toHonor);
}
});
但是简简单单的展示这些文字,完全没有一点吸引力,有吸引力的界面都是有动态交互的,所以我决定给这个列表的交互加一些动画,效果如下:
这有两个动画,第一个是点击了某一个条目之后和返回条目列表的动画,第二个是Activity切换的动画。
先说第二个动画,这个动画比较简单,我是基于主题来实现的,在Android中,AndroidManifest.xml文件中对Activity指定android:theme属性就可以设置主题了,如下:
<activity
android:name="com.xjy.resume.HonorActivity"
android:theme="@style/AppHonorTheme">
</activity>
然后再定义这个主题:
<style name="AppHonorTheme" parent="android:Theme.NoTitleBar">
<item name="android:windowAnimationStyle">@style/honorAnimation</item>
</style>
这个主题只有一个item,就是android:windowAnimationStyle,顾名思义,这个属性指定了窗口动画的样式,这个样式也是我们自己创建的,如下:
<style name="honorAnimation" parent="@android:style/Animation">
<item name="android:activityOpenEnterAnimation">@anim/bottomslidein_anim</item>
<item name="android:activityOpenExitAnimation">@anim/fadeout_anim</item>
<item name="android:activityCloseEnterAnimation">@anim/fadein_anim</item>
<item name="android:activityCloseExitAnimation">@anim/bottomslideout_anim</item>
</style>
关于这个样式的四个属性大家看名字也能看的到,也就是新打开的Activity进入退出的动画和旧Activity进入退出的动画,动画的定义由于代码比较多,占篇幅太大,我就不贴出来了,这里有四个链接:
bottomslidein_anim、 fadeout_anim、 fadein_anim、 bottomslideout_anim
如果觉得有必要解释这些动画的话,我会重新写一篇文章来介绍Android的动画。
现在要实现第一个动画了,因为要达到图片中那样像拉帘子一样的效果,所以我们针对每一个ListView的item都要做处理,思路如下:
1.获取到每个item。
2.为每个item添加一个左右方向压缩的动画。
3.每个动画都延迟一定时间执行。
4.最后一个动画执行完成之后跳转Activity。
思路一出来,代码写起来就很简单了,修改之前的代码后,如下:
honorsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,final int position, long id) {
int count = honorsListView.getChildCount();
for (int i = 0; i < count; i++) {
View child = honorsListView.getChildAt(i);//获取到item
ScaleAnimation sa = new ScaleAnimation(1.0f, 0.0f, 1.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0);//缩放动画,只缩放左右
sa.setDuration(500);//动画执行的时间
sa.setFillAfter(true);//这个一定要设置,不然动画执行完后item又会变回原来的样子
sa.setStartOffset((count - i)*50);//设置开始时间的偏移量,就是靠这个来实现拉帘子的效果
if (child != null) {
child.setAnimation(sa);//将动画设置给item
}
child.startAnimation(sa);//执行动画
}
//因为我们的拉帘子效果是从下面拉到上面,所以最后一个执行的动画是第一个item,给item设置一个
//AnimationListener,在onAnimationEnd中完成跳转Activity
honorsListView.getChildAt(0).getAnimation().setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
Intent toHonor = new Intent(context, HonorActivity.class);
toHonor.putExtra("id", position + 1);
startActivity(toHonor);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
});
第二步:自定义控件
做Android的开发,怎么能不会自定义控件呢,所以为了体现我掌握了这个技术,我专门在简历中自定义了一个图表控件:
通过这个控件,能够展示我对某一个技术的熟练度。自定义控件怎么做我也不详细的说,我们定义一个继承View的类。变量的初始化不是重点,各个变量的意义如下:
重点是继承onDraw来绘制这个控件,思路如下:
1.绘制一个内圆,内填充。
2.绘制一个外扇形,内部不填充,不连接圆心,边调粗一些。
3.绘制技能的名字。
话不多说,有了思路直接就有代码:
@Override
protected void onDraw(Canvas canvas) {
// Log.i("Ring","onDraw");
super.onDraw(canvas);
int width = canvas.getClipBounds().width();//获取高度
int center = width / 2;//计算中心点
int innerCircle = Math.round(center - this.ringWidth - 4); //设置内圆半径
int ringWidth = Math.round(this.ringWidth); //设置圆环宽度
//绘制内圆
Paint p = new Paint();
p.setStyle(Paint.Style.FILL);
p.setColor(skillColor);
p.setStrokeWidth(1);
canvas.drawCircle(center, center, innerCircle-20, p);
//绘制圆环
this.paint.setColor(skillColor);
//this.paint.setARGB(255, 212 ,225, 233);
this.paint.setStrokeWidth(ringWidth);
//创建绘制圆环的范围
RectF oval = new RectF();
oval.top = this.ringWidth / 2 + 2;
oval.left = this.ringWidth / 2 + 2;
oval.right = width - this.ringWidth / 2 - 2;
oval.bottom = width - this.ringWidth / 2 - 2;
//扫过的角度,也就是能力值,注意一定要用float计算,不然会算出0
float sweepAngle = (skillPoint / 100f) * 360f;
//绘制能力值
canvas.drawArc(oval, 270, sweepAngle, false, this.paint);
p.setTextSize(TEXT_SIZE);
p.setColor(skillTextColor);
p.setTextAlign(Paint.Align.CENTER);
canvas.drawText(skillText, 0, skillText.length(), center, center, p);
}
这个控件大概就是这样了,但是还有一些东西需要处理,比如点击、颜色根据能力改变等等,我们在下一篇文章中会继续讨论。
结尾+扯淡
下一篇文章会继承这篇文章创建的自定义控件,实现更多更强大的功能。
继续扯淡,其实我很想做Android,但是目前成熟一些的做Android的公司投了简历就像石沉大海,完全没有回应了,目前收到的offer也有几个,但是都是做J2EE的,是我最熟练的,却不是最感兴趣的。找工作好辛苦啊,坚持了这么久,也不能就这么放弃,继续加油吧~
脑袋里还有很多的想法,比如我即将要做的课程设计(协作平台)、或者是社交日历等,如果我以后动手实现了,我也一定会分享出来。
本项目已经托管到了 Github。