Android UI设计与开发之ViewPager仿微信引导界面以及动画效果

发布时间 - 2026-01-11 03:01:46    点击率:

基于前两篇比较简单的实例做铺垫之后,这一篇我们来实现一个稍微复杂一点的引导界面的效果,当然也只是稍微复杂了一点,对于会的人来说当然还是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; 
 } 
  
 /** 
 * 获得当前界面数 
 */ 
 @Override 
 public 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); 
 } 
 
 /** 
 * 判断是否由对象生成界面 
 */ 
 @Override 
 public 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来存放View 
 private 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; 
 
 @Override 
 protected 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); 
   
 // 实例化ViewPager 
 viewPager = (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() { 
  @Override 
  public void onClick(View v) { 
   startbutton(); 
  } 
 }); 
 } 
 
 public class MyOnPageChangeListener implements OnPageChangeListener { 
 @Override 
 public 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); 
 } 
 
 @Override 
 public void onPageScrollStateChanged(int arg0) { 
 
 } 
 
 @Override 
 public 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(){ 
  @Override 
  public 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 { 
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
 super.onCreate(savedInstanceState); 
 setContentView(R.layout.activity_other); 
 } 
} 

10、最后大家别忘了在AndroidManifest.xml清单文件中为程序添加GuideViewDoor、OtherActivity这两个activity,否则会报出异常。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# ViewPager微信引导界面  # ViewPager引导界面  # Android  # UI仿微信引导界面  # Android使用ViewPager实现启动引导页  # Android开发实战之漂亮的ViewPager引导页  # Android控件ViewPager实现带有动画的引导页  # Android开发实现的ViewPager引导页功能(动态加载指示器)详解  # Android利用ViewPager实现用户引导界面效果的方法  # Android UI设计与开发之使用ViewPager实现欢迎引导页面  # Android UI设计与开发之ViewPager介绍和简单实现引导界面  # android使用ViewPager组件实现app引导查看页面  # Android自定义引导玩转ViewPager的方法详解  # 这一  # 在这里  # 我会  # 主程序  # 自定义  # 在后面  # 来实现  # 的人  # 类中  # 的是  # 是一个  # 这是  # 我也  # 几个  # 我就  # 使用了  # 都有  # 有个  # 在这个  # 出了 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何处理CORS跨域请求?(配置示例)  如何快速搭建安全的FTP站点?  Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性  七夕网站制作视频,七夕大促活动怎么报名?  Laravel如何升级到最新版本?(升级指南和步骤)  javascript中的数组方法有哪些_如何利用数组方法简化数据处理  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  如何在IIS7上新建站点并设置安全权限?  Laravel如何从数据库删除数据_Laravel destroy和delete方法区别  Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】  Laravel怎么自定义错误页面_Laravel修改404和500页面模板  Laravel怎么连接多个数据库_Laravel多数据库连接配置  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】  WEB开发之注册页面验证码倒计时代码的实现  ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法  如何在云指建站中生成FTP站点?  香港服务器网站卡顿?如何解决网络延迟与负载问题?  什么是javascript作用域_全局和局部作用域有什么区别?  如何用美橙互联一键搭建多站合一网站?  Laravel的.env文件有什么用_Laravel环境变量配置与管理详解  如何续费美橙建站之星域名及服务?  如何在宝塔面板中创建新站点?  HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】  Laravel如何自定义错误页面(404, 500)?(代码示例)  如何确保西部建站助手FTP传输的安全性?  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  网站页面设计需要考虑到这些问题  详解阿里云nginx服务器多站点的配置  JS碰撞运动实现方法详解  百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧  如何快速生成ASP一键建站模板并优化安全性?  JavaScript模板引擎Template.js使用详解  北京企业网站设计制作公司,北京铁路集团官方网站?  Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知  Edge浏览器如何截图和滚动截图_微软Edge网页捕获功能使用教程【技巧】  香港服务器租用每月最低只需15元?  googleplay官方入口在哪里_Google Play官方商店快速入口指南  jQuery validate插件功能与用法详解  laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  如何在万网自助建站平台快速创建网站?  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?  如何正确下载安装西数主机建站助手?  JavaScript如何实现路由_前端路由原理是什么  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】  香港服务器建站指南:外贸独立站搭建与跨境电商配置流程  Laravel如何设置自定义的日志文件名_Laravel根据日期或用户ID生成动态日志【技巧】