【Android(安卓)UI设计与开发】第03期:引导界面(三)仿微信引导界面以及动画效果
16lz
2021-01-25
转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/8985457
基于前两篇比较简单的实例做铺垫之后,这一篇我们来实现一个稍微复杂一点的引导界面的效果,当然也只是稍微复杂了一点,对于会的人来说当然还是so easy!正所谓会者不难,难者不会,大概说的就是这个意思了吧。好的,话不多说,回归正题。
这篇要实现的是一个仿微信的动画效果,虽然这种效果的实现在网上到处都有,但是我还是想站在中低端开发者的角度去告诉大家是如何实现的,当然实现的方式有很多,我也只是列出了我认为实现起来比较方便的一种方法,希望大家能够受用。
一、实现的效果图
有图才有真相,上图先:
点击按钮后出现动画效果,然后进入到另一个界面:
二 、程序的目录结构
三、具体的编码实现
1、在主布局界面中加入ViewPager组件,以及底部的小点,activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" > <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <LinearLayout android:id="@+id/ll" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="24.0dip" android:orientation="horizontal" > <ImageView android:id="@+id/page0" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="5dip" android:src="@drawable/page_indicator_focused" /> <ImageView android:id="@+id/page1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="5dip" android:src="@drawable/page_indicator_unfocused" /> <ImageView android:id="@+id/page2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="5dip" android:src="@drawable/page_indicator_unfocused" /> <ImageView android:id="@+id/page3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="5dip" android:src="@drawable/page_indicator_unfocused" /> <ImageView android:id="@+id/page4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="5dip" android:src="@drawable/page_indicator_unfocused" /> <ImageView android:id="@+id/page5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="5dip" android:src="@drawable/page_indicator_unfocused" /> </LinearLayout></RelativeLayout>2、接着在guide_view01.xml等几个布局页面中添加引导界面要显示的图片和控件,因为这几个布局界面都大同小异,所以在这里我就不一一贴出来了吧,有需要的同学可以直接下载源码,guide_view01.xml:
<?xml version="1.0" encoding="UTF-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/w01" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_marginTop="35dp" android:gravity="center" android:text="@string/guide_text01" android:textColor="@color/TextColor" android:textSize="22sp" /></RelativeLayout>3、然后是要实现动画效果的布局界面,guide_door.xml:
<?xml version="1.0" encoding="UTF-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:id="@+id/imageLeft" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentLeft="true" android:scaleType="fitXY" android:src="@drawable/w_left" /> <ImageView android:id="@+id/imageRight" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentRight="true" android:scaleType="fitXY" android:src="@drawable/w_right" android:visibility="visible" /> <TextView android:id="@+id/anim_text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_marginTop="35dp" android:gravity="center" android:text=" \n \n微信,是一个生活方式\n \n " android:textColor="#fff" android:textSize="22sp" /></RelativeLayout>4、最后是完成动画效果之后进入的布局界面,activity_other.xml:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="亲,可以开始你的微信生活了!" /></LinearLayout>5、在这里还要创建一个xml文件来实现自定义按钮的效果,关于自定义按钮的效果实现我会在后面的文章中专题详细介绍,这里就不在赘述,start_weixin_btn.xml:
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_enabled="true" android:state_pressed="true"android:drawable="@drawable/whatsnew_btn_pressed" /> <!--按下时的效果--><item android:state_enabled="true" android:drawable="@drawable/whatsnew_btn_nor" /> <!--正常状态的效果--></selector>6、布局界面已经讲解完毕,接下来让我们进行详细的代码讲解,ViewPager适配器代码,ViewPagerAdapter.java:
package com.yangyu.myguideview02;import java.util.ArrayList;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.view.View;/** * @author yangyu * 功能描述:ViewPager适配器,用来绑定数据和view */public class ViewPagerAdapter extends PagerAdapter { //界面列表 private ArrayList<View> views; public ViewPagerAdapter (ArrayList<View> views){ this.views = views; } /** * 获得当前界面数 */@Overridepublic int getCount() { if (views != null) { return views.size(); } return 0;}/** * 初始化position位置的界面 */ @Override public Object instantiateItem(View view, int position) { ((ViewPager) view).addView(views.get(position), 0); return views.get(position); } /** * 判断是否由对象生成界面 */@Overridepublic boolean isViewFromObject(View view, Object arg1) {return (view == arg1);}/** * 销毁position位置的界面 */ @Override public void destroyItem(View view, int position, Object arg2) { ((ViewPager) view).removeView(views.get(position)); }}7、主程序入口activity类,MainActivity.java:
package com.yangyu.myguideview02;import java.util.ArrayList;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;/** * @author yangyu * 功能描述:主程序入口activity */public class MainActivity extends Activity {// 定义ViewPager对象private ViewPager viewPager;// 定义ViewPager适配器private ViewPagerAdapter vpAdapter;// 定义一个ArrayList来存放Viewprivate ArrayList<View> views;//定义各个界面View对象private View view1,view2,view3,view4,view5,view6;// 定义底部小点图片private ImageView pointImage0, pointImage1, pointImage2, pointImage3,pointImage4, pointImage5;//定义开始按钮对象private Button startBt;// 当前的位置索引值private int currIndex = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initData();}/** * 初始化组件 */private void initView() {//实例化各个界面的布局对象 LayoutInflater mLi = LayoutInflater.from(this);view1 = mLi.inflate(R.layout.guide_view01, null);view2 = mLi.inflate(R.layout.guide_view02, null);view3 = mLi.inflate(R.layout.guide_view03, null);view4 = mLi.inflate(R.layout.guide_view04, null);view5 = mLi.inflate(R.layout.guide_view05, null);view6 = mLi.inflate(R.layout.guide_view06, null);// 实例化ViewPagerviewPager = (ViewPager) findViewById(R.id.viewpager);// 实例化ArrayList对象views = new ArrayList<View>();// 实例化ViewPager适配器vpAdapter = new ViewPagerAdapter(views);// 实例化底部小点图片对象pointImage0 = (ImageView) findViewById(R.id.page0);pointImage1 = (ImageView) findViewById(R.id.page1);pointImage2 = (ImageView) findViewById(R.id.page2);pointImage3 = (ImageView) findViewById(R.id.page3);pointImage4 = (ImageView) findViewById(R.id.page4);pointImage5 = (ImageView) findViewById(R.id.page5);//实例化开始按钮startBt = (Button) view6.findViewById(R.id.startBtn);}/** * 初始化数据 */private void initData() {// 设置监听viewPager.setOnPageChangeListener(new MyOnPageChangeListener());// 设置适配器数据viewPager.setAdapter(vpAdapter);//将要分页显示的View装入数组中views.add(view1);views.add(view2);views.add(view3);views.add(view4);views.add(view5);views.add(view6);// 给开始按钮设置监听startBt.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) { startbutton();}});}public class MyOnPageChangeListener implements OnPageChangeListener {@Overridepublic void onPageSelected(int position) {switch (position) {case 0:pointImage0.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_focused));pointImage1.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_unfocused));break;case 1:pointImage1.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_focused));pointImage0.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_unfocused));pointImage2.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_unfocused));break;case 2:pointImage2.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_focused));pointImage1.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_unfocused));pointImage3.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_unfocused));break;case 3:pointImage3.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_focused));pointImage4.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_unfocused));pointImage2.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_unfocused));break;case 4:pointImage4.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_focused));pointImage3.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_unfocused));pointImage5.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_unfocused));break;case 5:pointImage5.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_focused));pointImage4.setImageDrawable(getResources().getDrawable(R.drawable.page_indicator_unfocused));break;}currIndex = position;// animation.setFillAfter(true);// True:图片停在动画结束位置// animation.setDuration(300);// mPageImg.startAnimation(animation);}@Overridepublic void onPageScrollStateChanged(int arg0) {}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {}}/** * 相应按钮点击事件 */private void startbutton() { Intent intent = new Intent();intent.setClass(MainActivity.this,GuideViewDoor.class);startActivity(intent);this.finish(); }}PS:在这段代码中,有个地方需要注意,尽管我们写代码的时候一直很小心,但还是避免不了会犯一些低级的错误,以至于调试耽误了时间
//实例化开始按钮startBt = (Button) view6.findViewById(R.id.startBtn);这是最后一个布局界面中的一个开始按钮,由于在findvViewById()方法前面忘记使用了view6来调用该方法,以至于模拟器报出空指针异常。
8、实现动画效果的入口activity类,在这个类中主要实现了点击开始按钮后实现一个动画效果来达到进入另一个界面的目的,该类中的主要使用了动画类。我会在后面的章节中以专题的形式来介绍动画这一块的类容,所以这里也不再赘述,GuideViewDoor.java:
package com.yangyu.myguideview02;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.view.animation.AlphaAnimation;import android.view.animation.Animation;import android.view.animation.AnimationSet;import android.view.animation.ScaleAnimation;import android.view.animation.TranslateAnimation;import android.widget.ImageView;import android.widget.TextView;/** * @author yangyu * 功能描述:实现动画效果的入口activity */public class GuideViewDoor extends Activity {//定义左右两张图片对象private ImageView mLeft,mRight;//定义一个文本对象private TextView mText; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.guide_door); //实例化对象 mLeft = (ImageView)findViewById(R.id.imageLeft); mRight = (ImageView)findViewById(R.id.imageRight); mText = (TextView)findViewById(R.id.anim_text); //实例化动画对象 AnimationSet anim = new AnimationSet(true); //实例化位移动画对象TranslateAnimation mytranslateanim = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,-1f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f); //设置动画持续时间mytranslateanim.setDuration(2000);//设置启动时间anim.setStartOffset(800);//将位移动画添加进动画效果中anim.addAnimation(mytranslateanim);//动画结束后,保留在终止位anim.setFillAfter(true);//左边图启动该动画效果mLeft.startAnimation(anim);AnimationSet anim1 = new AnimationSet(true);TranslateAnimation mytranslateanim1 = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,+1f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f);mytranslateanim1.setDuration(1500);anim1.addAnimation(mytranslateanim1);anim1.setStartOffset(800);anim1.setFillAfter(true);mRight.startAnimation(anim1);AnimationSet anim2 = new AnimationSet(true);ScaleAnimation myscaleanim = new ScaleAnimation(1f,3f,1f,3f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);myscaleanim.setDuration(1000);AlphaAnimation myalphaanim = new AlphaAnimation(1,0.0001f);myalphaanim.setDuration(1500);anim2.addAnimation(myscaleanim);anim2.addAnimation(myalphaanim);anim2.setFillAfter(true);mText.startAnimation(anim2);new Handler().postDelayed(new Runnable(){@Overridepublic void run(){Intent intent = new Intent (GuideViewDoor.this,OtherActivity.class);startActivity(intent);GuideViewDoor.this.finish();}}, 2300); }}9、最后是另一个activity类,我为了只是达到进入到另一个界面的这种效果,所以代码比较简单,就是调用了一个layout布局页面, OtherActivity.java:
package com.yangyu.myguideview02;import android.app.Activity;import android.os.Bundle;/** * @author yangyu * 功能描述:另一个activity */public class OtherActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_other);}}10、最后大家别忘了在AndroidManifest.xml清单文件中为程序添加GuideViewDoor、OtherActivity这两个activity,否则会报出异常。
源码下载地址
更多相关文章
- 模仿微信界面tabhost底部导航——使用继承ActivityGroup方式
- 随手记----Android仿iOS音量调节的效果
- Libgdx 之SpriteBatch深入分析
- Android(安卓)TV Menu 3D星体旋转效果
- Android实现不重复启动APP的方法android:alwaysRetainTaskState
- Android客户端首次启动时的引导界面(viewpager)
- Material Design设计规范
- 关于Android中apk使用不同的签名(key)的测试
- Android小项目之十一 应用程序的主界面