热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

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

基于前两篇比较简单的实例做铺垫之后,这一篇我们来实现一个稍微复杂一点的引导界面的效果,当然也只是稍微复杂了一点,对于会的人来说当然还是so

基于前两篇比较简单的实例做铺垫之后,这一篇我们来实现一个稍微复杂一点的引导界面的效果,当然也只是稍微复杂了一点,对于会的人来说当然还是so easy!正所谓会者不难,难者不会,大概说的就是这个意思了吧。好的,话不多说,回归正题。

这篇要实现的是一个仿微信的动画效果,虽然这种效果的实现在网上到处都有,但是我还是想站在中低端开发者的角度去告诉大家是如何实现的,当然实现的方式有很多,我也只是列出了我认为实现起来比较方便的一种方法,希望大家能够受用。  

一、实现的效果图

有图才有真相,上图先:

点击按钮后出现动画效果,然后进入到另一个界面:

二 、程序的目录结构

三、具体的编码实现

1、  在主布局界面中加入ViewPager组件,以及底部的小点,activity_main.xml:

 
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
  
 

2、接着在guide_view01.xml等几个布局页面中添加引导界面要显示的图片和控件,因为这几个布局界面都大同小异,所以在这里我就不一一贴出来了吧,有需要的同学可以直接下载源码,guide_view01.xml:

<&#63;xml version="1.0" encoding="UTF-8"&#63;> 
 
 
  
 

3、然后是要实现动画效果的布局界面,guide_door.xml:

<&#63;xml version="1.0" encoding="UTF-8"&#63;> 
 
 
  
 
  
 
  

 4、最后是完成动画效果之后进入的布局界面,activity_other.xml:

<&#63;xml version="1.0" encoding="utf-8"&#63;> 
 
 
  

 5、在这里还要创建一个xml文件来实现自定义按钮的效果,关于自定义按钮的效果实现我会在后面的文章中专题详细介绍,这里就不在赘述,start_weixin_btn.xml:

<&#63;xml version="1.0" encoding="utf-8"&#63;> 
 
    
  
   
 

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 views; 
 
 public ViewPagerAdapter (ArrayList 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 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(); 
 
 // 实例化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,否则会报出异常。

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


推荐阅读
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 解决微信电脑版无法刷朋友圈问题:使用安卓远程投屏方案
    在工作期间想要浏览微信和朋友圈却不太方便?虽然微信电脑版目前不支持直接刷朋友圈,但通过远程投屏技术,可以轻松实现在电脑上操作安卓设备的功能。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 本文介绍如何使用布局文件在Android应用中排列多行TextView和Button,使其占据屏幕的特定比例,并提供示例代码以帮助理解和实现。 ... [详细]
  • 本文介绍了Android开发中Intent的基本概念及其在不同Activity之间的数据传递方式,详细展示了如何通过Intent实现Activity间的跳转和数据传输。 ... [详细]
  • 优化 Android 按钮状态下的背景和文本颜色变化
    本文介绍如何通过 Android 的 Selector 实现按钮在不同状态下(如按压)的背景和文本颜色动态变化。我们将详细讲解实现步骤,并提供完整的代码示例。 ... [详细]
  • 非公版RTX 3080显卡的革新与亮点
    本文深入探讨了图形显卡的进化历程,重点介绍了非公版RTX 3080显卡的技术特点和创新设计。 ... [详细]
  • 本文详细介绍如何使用arm-eabi-gdb调试Android平台上的C/C++程序。通过具体步骤和实用技巧,帮助开发者更高效地进行调试工作。 ... [详细]
  • 深入理解 Oracle 存储函数:计算员工年收入
    本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
author-avatar
实圪垯电动乐园_855
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有