涉及技术
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。