热门标签 | 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,否则会报出异常。

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


推荐阅读
  • 本文探讨了如何有效地构建和优化微信公众平台账号,涵盖了用户信息管理、内容创作与发布、互动策略及数据分析等方面。通过合理设置用户信息字段,如用户名、昵称、密码、真实姓名和性别等,确保账号的安全性和用户体验。同时,文章还介绍了如何利用微信公众平台的各项功能,提升用户参与度和品牌影响力。 ... [详细]
  • 在 Android 应用开发中,实现全屏模式和无标题栏设计是提升用户体验的重要手段。本文详细介绍了如何通过 Java 代码实现取消标题栏 `this.requestWindowFeature(Window.FEATURE_NO_TITLE)`,并进一步探讨了全屏模式的多种实现方法和最佳实践,帮助开发者打造更加沉浸式和美观的用户界面。 ... [详细]
  • 在Android开发中,BroadcastReceiver(广播接收器)是一个重要的组件,广泛应用于多种场景。本文将深入解析BroadcastReceiver的工作原理、应用场景及其具体实现方法,帮助开发者更好地理解和使用这一组件。通过实例分析,文章详细探讨了静态广播的注册方式、生命周期管理以及常见问题的解决策略,为开发者提供全面的技术指导。 ... [详细]
  • 提升Android开发效率:Clean Code的最佳实践与应用
    在Android开发中,提高代码质量和开发效率是至关重要的。本文介绍了如何通过Clean Code的最佳实践来优化Android应用的开发流程。以SQLite数据库操作为例,详细探讨了如何编写高效、可维护的SQL查询语句,并将其结果封装为Java对象。通过遵循这些最佳实践,开发者可以显著提升代码的可读性和可维护性,从而加快开发速度并减少错误。 ... [详细]
  • 在探讨Hibernate框架的高级特性时,缓存机制和懒加载策略是提升数据操作效率的关键要素。缓存策略能够显著减少数据库访问次数,从而提高应用性能,特别是在处理频繁访问的数据时。Hibernate提供了多层次的缓存支持,包括一级缓存和二级缓存,以满足不同场景下的需求。懒加载策略则通过按需加载关联对象,进一步优化了资源利用和响应时间。本文将深入分析这些机制的实现原理及其最佳实践。 ... [详细]
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 掌握这些技巧,轻松获取超过90%的资源信息
    在数字时代,高效获取所需资源是每个人必备的技能。本文将分享一系列实用技巧,帮助读者轻松获取超过90%的网络资源信息,无论是学术资料、技术文档还是最新资讯,都能迅速找到。通过优化搜索引擎使用、利用专业数据库和社群资源等方法,读者将能够在信息海洋中游刃有余。 ... [详细]
  • 在Android平台上,视频监控系统的优化与应用具有重要意义。尽管已有相关示例(如http:www.open-open.comlibviewopen1346400423609.html)展示了基本的监控功能实现,但若要提升系统的稳定性和性能,仍需进行深入研究和优化。本文探讨了如何通过改进算法、优化网络传输和增强用户界面来提高Android视频监控系统的整体效能,以满足更复杂的应用需求。 ... [详细]
  • 推荐一款出色的移动应用原型设计工具——Tiggr(http://gotiggr.com)。该工具基于Flash技术开发,支持Web、iPhone和Android等多种平台的原型设计。虽然需要注册账号才能使用,但其强大的功能和易用性使其成为开发者和设计师的理想选择。 ... [详细]
  • 将解压缩版Tomcat集成至系统服务
    将解压缩版Tomcat集成至系统服务的方法如下:首先,在命令行中导航至Tomcat的`bin`目录,运行`service.bat install`命令以安装服务。需要注意的是,服务名称和显示名称已在`service.bat`脚本中预设,默认情况下会随不同版本有所变化。此外,建议检查并配置相关参数,确保服务能够稳定运行。 ... [详细]
  • 题目探讨了在无向图中求解点连通数的问题,具体涉及UVA1660和POJ1966两个经典问题。通过最小割算法的应用,分析了如何高效地确定网络中的关键节点和路径,为电缆电视网络的优化设计提供了理论支持。该研究不仅验证了最小割算法的有效性,还为进一步探索复杂网络的连通性和鲁棒性奠定了基础。 ... [详细]
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • POJ3669题目解析:基于广度优先搜索的详细解答
    POJ3669(http://poj.org/problem?id=3669)是一道典型的广度优先搜索(BFS)问题。由于陨石的降落具有时间属性,导致地图状态会随时间动态变化。因此,可以利用结构体来记录每个陨石的降落时间和位置,从而有效地进行状态更新和路径搜索。 ... [详细]
  • 如何高效地安装并配置 PostgreSQL 数据库系统?本文将详细介绍从下载到安装、配置环境变量、初始化数据库、以及优化性能的全过程,帮助读者快速掌握 PostgreSQL 的核心操作与最佳实践。文章还涵盖了常见问题的解决方案,确保用户在部署过程中能够顺利解决遇到的各种挑战。 ... [详细]
  • C# .NET 4.1 版本大型信息化系统集成平台中的主从表事务处理标准示例
    在C# .NET 4.1版本的大型信息化系统集成平台中,本文详细介绍了主从表事务处理的标准示例。通过确保所有操作要么全部成功,要么全部失败,实现主表和关联子表的同步插入。主表插入时会返回当前生成的主键,该主键随后用于子表插入时的关联。以下是一个示例代码片段,展示了如何在一个数据库事务中同时添加角色和相关用户。 ... [详细]
author-avatar
tigerweilong
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有