`

程序第一次安装使用,类似于微信的新特性介绍界面的实现

 
阅读更多

先看效果:

 

 

这个效果实现起来相对比较复杂,我们先看下都有哪些文件:

 

滑动的效果我使用的是viewPager,使用这个类需要导入兼容包android-support-v4.jar

导入的方法很简单,这里就不说了。你可以百度下,或者下载我的demo,把里面的包拿出来使用都行。

 

下面直接看代码吧:

DotMarks.java

 

/**
 * This class is used to wrap the dot marks which displayed in the bottom of the View
 * 这个类将底部的显示页面索引的小标记包装起来
 * 
 * @author Michael 叶坤
 * @since 2012-08-07
 * */
public class DotMarks extends LinearLayout
{

	public DotMarks(Context context, AttributeSet attrs) {
		super(context, attrs);
		ini(context);
	}

	public DotMarks(Context context) {
		super(context);
		ini(context);
	}

	private ImageView viewOne;
	private ImageView viewTwo;
	private ImageView viewThree;
	private ImageView viewFour;
	private ImageView viewFive;
	
	private void ini(Context context)
	{
		LayoutInflater mInflater = ((Activity)context).getLayoutInflater();
		View dotViews = mInflater.inflate(R.layout.dot_marks, null);
		this.addView(dotViews);
		viewOne = (ImageView)dotViews.findViewById(R.id.iv_one);
		viewTwo = (ImageView)dotViews.findViewById(R.id.iv_two);
		viewThree = (ImageView)dotViews.findViewById(R.id.iv_three);
		viewFour = (ImageView)dotViews.findViewById(R.id.iv_four);
		viewFive = (ImageView)dotViews.findViewById(R.id.iv_five);
		
		//initialize the dots
		viewOne.setImageDrawable(whiteDot);
		viewTwo.setImageDrawable(darkDot);
		viewThree.setImageDrawable(darkDot);
		viewFour.setImageDrawable(darkDot);
		viewFive.setImageDrawable(darkDot);
	}
	
	/**
	 * display the dot marks dynamic by the viewPager index which passed in
	 * 
	 * 根据传递进来的页面的索引切换小图标的显示
	 * 
	 * */
	private Drawable whiteDot = this.getResources().getDrawable(R.drawable.dot_white);
	private Drawable darkDot = this.getResources().getDrawable(R.drawable.dot_dark);
	public void updateMark(int index)
	{
		switch(index)
		{
		case 0:
			viewOne.setImageDrawable(whiteDot);
			viewTwo.setImageDrawable(darkDot);
			viewThree.setImageDrawable(darkDot);
			viewFour.setImageDrawable(darkDot);
			viewFive.setImageDrawable(darkDot);
			break;
		case 1:
			viewOne.setImageDrawable(darkDot);
			viewTwo.setImageDrawable(whiteDot);
			viewThree.setImageDrawable(darkDot);
			viewFour.setImageDrawable(darkDot);
			viewFive.setImageDrawable(darkDot);
			break;
		case 2:
			viewOne.setImageDrawable(darkDot);
			viewTwo.setImageDrawable(darkDot);
			viewThree.setImageDrawable(whiteDot);
			viewFour.setImageDrawable(darkDot);
			viewFive.setImageDrawable(darkDot);
			break;
		case 3:
			viewOne.setImageDrawable(darkDot);
			viewTwo.setImageDrawable(darkDot);
			viewThree.setImageDrawable(darkDot);
			viewFour.setImageDrawable(whiteDot);
			viewFive.setImageDrawable(darkDot);
			break;
		case 4:
			viewOne.setImageDrawable(darkDot);
			viewTwo.setImageDrawable(darkDot);
			viewThree.setImageDrawable(darkDot);
			viewFour.setImageDrawable(darkDot);
			viewFive.setImageDrawable(whiteDot);
			break;
		}
	}
}
 

WhatIsNewAdapter.java

 

/**
 * The ViewPager's adapter,just override these methods
 * 
 * ViewPager的适配器,覆写它的方法就好了
 * 
 * @author Michael 叶坤
 * @since 2012-08-07
 * */
public class WhatIsNewAdapter extends PagerAdapter {
	public List<View> mListViews;

	public WhatIsNewAdapter(List<View> mListViews) {
		this.mListViews = mListViews;
	}

	@Override
	public void destroyItem(View arg0, int arg1, Object arg2) {
		((ViewPager) arg0).removeView(mListViews.get(arg1));
	}

	@Override
	public void finishUpdate(View arg0) {
	}

	@Override
	public int getCount() {
		return mListViews.size();
	}

	@Override
	public Object instantiateItem(View arg0, int arg1) {
		((ViewPager) arg0).addView(mListViews.get(arg1), 0);
		return mListViews.get(arg1);
	}

	@Override
	public boolean isViewFromObject(View arg0, Object arg1) {
		return arg0 == (arg1);
	}

	@Override
	public void restoreState(Parcelable arg0, ClassLoader arg1) {
	}

	@Override
	public Parcelable saveState() {
		return null;
	}

	@Override
	public void startUpdate(View arg0) {
	}
}

 

WhatIsNewUtils.java

/**
 * This class is used for :
 * judge whether the application is first been used.-->isFirstUse(Context context)
 * And save the data if users has opened the application.-->saveFirstUseFlag(Context context)
 * 
 * example:when user open the application first time ,the method isFirstUse(Context context)will return true.
 * after user opened the application,the method saveFirstUseFlag(Context context) should be called
 * so that when user opened the application next time ,the method isFirstUse(Context context)will return false.
 * 
 * see MainActivity.java to know how to use these methods.
 * 
 * 
 * 
 * 这个类用来判断应用程序是否是第一次使用-->isFirstUse(Context context)
 * 如果用户打开过了这个程序,将标记保存-->saveFirstUseFlag(Context context)
 * 
 * 例如:当用户第一次打开应用程序的时候,isFirstUse(Context context)方法返回的是true.
 * 之后你可以调用saveFirstUseFlag(Context context)方法。这样下次用户再打开程序员的时候
 * isFirstUse(Context context)方法返回的是false.
 * 
 * 具体使用,参见MainActivity.java 
 * 
 * @author Michael 叶坤
 * @since 2012-08-07
 * */
public class WhatIsNewUtils 
{

	private static String WHAT_IS_NEW_PRE_NAME = "what_is_new_pre_name";
	
	private static String FIRST_USE_FLAG = "first_use_flag";
	 /**
	  * judge whether the first time to use this application
	  * 
      * 判断是否是第一次使用该应用程序
      * 
      * */
    public static boolean isFirstUse(Context context)
    {
    	SharedPreferences sharedPreferences = context.getSharedPreferences(WHAT_IS_NEW_PRE_NAME, Activity.MODE_PRIVATE);
        boolean flag = sharedPreferences.getBoolean(FIRST_USE_FLAG, true);
        return flag;
    }
    
    /**
     * save the flag of first use the application
     * 
     * 保存第一次使用的信息
     * 
     * */
    public static void saveFirstUseFlag(Context context)
    {
    	SharedPreferences sharedPreferences = context.getSharedPreferences(WHAT_IS_NEW_PRE_NAME, Activity.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putBoolean(FIRST_USE_FLAG, false);
        editor.commit();
    }
    
}
 

WhatIsNewView.java

/**
 * This class encapsulate the View which used for introduce something new of your application,
 * or how to use your application etc to users.Of course,you can also encapsulate this in a Activity,
 * but if you do that, you can not achieve the effect of animations perfectly.
 * So,I decide to encapsulate this in a LinearLayout(View).Because most animations 
 * can be achieve perfectly in the same Activity,not between two Activity. 
 * You can do this by use the method setContentView();
 * 
 * setContentView(R.layout.activity_main);
 * setContentView(new WhatIsNewView(context));
 * just switch these method dynamic in the same Activity MainActivity.java.
 * 
 * 
 * 
 * 一般应用程序第一次使用的时候,都有一个关于你的程序的新特性,或者任何是任何使用你的程序的介绍等等。
 * 你可以把这个功能封装在一个Activity里面,但是这样做有一点不好的地方,当你要实现一些动画效果的时候,
 * 在Activity之间实现起来不是很完美,会闪一下,为了实现类似微信那样的效果,我们需要将它封装为一个View
 * 也就是说和程序的主界面在同一个Activity中,通过setContentView方法来切换视图,这样就可以较好的实现效果
 * 而且不需要在Manifest中申明一个Activity,也方便使用。
 * 
 * @author Michael 叶坤
 * 
 * @since 2012-08-07
 * */
public class WhatIsNewView extends LinearLayout {

	private Context context;
	private ImageView ivLeftImage;
	private ImageView ivRightImage;
	private TextView tvLeftButton;
	private TextView tvRightButton;
	private DotMarks dotViews;
	
	public WhatIsNewView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
		ini(context);
	}

	public WhatIsNewView(Context context) {
		super(context);
		this.context = context;
		ini(context);
	}

	private void ini(Context context)
	{
		LayoutInflater mInflater = ((Activity)context).getLayoutInflater();
		View layoutWhatIsNew = mInflater.inflate(R.layout.layout_what_is_new, null);
		View viewPagerOne = mInflater.inflate(R.layout.viewpager_one, null);
		View viewPagerTwo = mInflater.inflate(R.layout.viewpager_two, null);
        View viewPagerThree = mInflater.inflate(R.layout.viewpager_three, null);
        View viewPagerFour = mInflater.inflate(R.layout.viewpager_four, null);
        View viewPagerFive = mInflater.inflate(R.layout.viewpager_five, null);
        ViewPager viewPager = (ViewPager)layoutWhatIsNew.findViewById(R.id.view_pager);
        List<View> viewItems = new ArrayList<View>();
        viewItems.add(viewPagerOne);
        viewItems.add(viewPagerTwo);
        viewItems.add(viewPagerThree);
        viewItems.add(viewPagerFour);
        viewItems.add(viewPagerFive);
        viewPager.setAdapter(new WhatIsNewAdapter(viewItems));
        dotViews = (DotMarks)layoutWhatIsNew.findViewById(R.id.dot_marks);
        viewPager.setOnPageChangeListener(new OnPageChangeListener() {
			
        	/**
        	 * Update the marks when viewPager's index changed
        	 * 根据ViewPager的页面的变化来实时更新索引小图标
        	 * 
        	 * */
			@Override
			public void onPageSelected(int arg0) {
				dotViews.updateMark(arg0);
			}
			
			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
				
			}
			
			@Override
			public void onPageScrollStateChanged(int arg0) {
				
			}
		});
        
        ivLeftImage = (ImageView)viewPagerFive.findViewById(R.id.iv_left_image01);
        ivRightImage = (ImageView)viewPagerFive.findViewById(R.id.iv_left_image02);
        LinearLayout llStartApp = (LinearLayout)viewPagerFive.findViewById(R.id.ll_start_app);
        tvLeftButton = (TextView)viewPagerFive.findViewById(R.id.tv_left_btn01);
        tvRightButton = (TextView)viewPagerFive.findViewById(R.id.tv_left_btn02);
        llStartApp.setOnClickListener(new OnClickListener() {
			
        	/**
        	 * Here you can do some animations and finish this Activity 
        	 * 
        	 * 这里你可以执行一些界面切换的动画,并finish这个Activity
        	 *
        	 * */
			@Override
			public void onClick(View v) {
				startAnimation();
			}
		});
        
        this.addView(layoutWhatIsNew);
        
	}

	
	/**
	 * startAnimation
	 * 
	 * 开始动画
	 * 
	 * */
	private void startAnimation()
	{
		Animation leftAnim = AnimationUtils.loadAnimation(context, R.anim.slide_left_anim);
		Animation rightAnim = AnimationUtils.loadAnimation(context, R.anim.slide_right_anim);
		final Animation fadeAnim = AnimationUtils.loadAnimation(context, R.anim.fade_anim);
		leftAnim.setFillAfter(true);
		rightAnim.setFillAfter(true);
		rightAnim.setAnimationListener(new AnimationListener() {
			
			@Override
			public void onAnimationStart(Animation animation) {
				if(onAnimListener != null)
				{
					onAnimListener.onAnimationStart();
					dotViews.startAnimation(fadeAnim);
				}
			}
			
			@Override
			public void onAnimationRepeat(Animation animation) {
				
			}
			
			@Override
			public void onAnimationEnd(Animation animation) {
				if(onAnimListener != null)
				{
					onAnimListener.onAnimationEnd();
				}
			}
		});
		ivLeftImage.startAnimation(leftAnim);
		tvLeftButton.startAnimation(leftAnim);
		ivRightImage.startAnimation(rightAnim);
		tvRightButton.startAnimation(rightAnim);
	}
	
	private OnAppAnimationListener onAnimListener;
	
	/**
	 * Here add a listener,to listen the event of animation started and ended.
	 * 
	 * 这里设置一个监听,当动画开始和结束的时候通知外面setContentView改变
	 * 
	 * */
	public interface OnAppAnimationListener
	{
		public void onAnimationStart();
		
		public void onAnimationEnd();
	}
	
	public void setOnAppAnimationListener(OnAppAnimationListener onAnimListener)
	{
		this.onAnimListener = onAnimListener;
	}
}

 

 

 

最后看看是如何使用的:

 

/**
 * 
 * This is the MainActivity of the Application
 * 
 * 这个是程序的主界面
 * 
 * @author Michael 叶坤
 * @since 2012-08-07
 * */
public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        									//judge the application is first used
        									//判断是否是第一次使用
        if(WhatIsNewUtils.isFirstUse(MainActivity.this))
        {
        	showWhatIsNew();
        }
        else
        {
        	setContentView(R.layout.activity_main);//normally
        }
        
    }
    
    /**
     * show something about you application
     * 
     * 显示关于你的程序的介绍
     * */
    private void showWhatIsNew()
    {
    	WhatIsNewView whatIsNewView = new WhatIsNewView(MainActivity.this);
    	whatIsNewView.setOnAppAnimationListener(new OnAppAnimationListener() {
			
			@Override
			public void onAnimationStart() {
				
			}
			
			@Override
			public void onAnimationEnd() {
				LayoutInflater mInflater = MainActivity.this.getLayoutInflater();
	    		final View mainActivityView = mInflater.inflate(R.layout.activity_main, null);
				setContentView(mainActivityView);
				Animation enterAnim = AnimationUtils.loadAnimation(MainActivity.this, R.anim.main_activity_enter_anim);
				enterAnim.setFillAfter(true);
				mainActivityView.startAnimation(enterAnim);
			}
		});
    	setContentView(whatIsNewView);
    	
    	//save the flag ,so next time when user open this application,WhatIsNewUtils.isFirstUse(MainActivity.this) will return false
    	//保存标记,下一次打开程序WhatIsNewUtils.isFirstUse(MainActivity.this)返回的是false
    	WhatIsNewUtils.saveFirstUseFlag(MainActivity.this);
    }

}
 

 

代码中应该可以看出思路。布局文件和动画文件太多了,这里就不贴了,如果有兴趣您可以下载我的demo参看。如果发现问题欢迎指正。

 

demo下载地址:https://github.com/michaelye/DemoWhatIsNewComponent

 

 

 

 

 

 

 

 

 

 

 

  • 大小: 186.1 KB
  • 大小: 89.4 KB
分享到:
评论

相关推荐

    微信小程序项目实例-微信商城小程序源码纯前端项目

    微信小程序是一种轻量级的应用开发平台,主要针对移动端,尤其在微信生态系统内,为企业和个人提供了一种无需安装即可使用的应用方式。本项目实例是“微信商城小程序源码”,旨在为开发者提供一个完整的纯前端项目,...

    微信记账小程序_微信小程序模板js代码前台前端H5页面源码.rar

    微信小程序是一种轻量级的应用开发平台,由腾讯公司于2017年推出,旨在提供一种无需下载安装即可使用的应用体验。它介于传统的原生App和网页应用之间,用户可以通过微信内置的浏览器引擎运行小程序,享受到快速、...

    仿微信界面源码

    【仿微信界面源码】是一个专门用于开发类似微信应用界面的源代码库,它提供了实现微信界面风格的各种组件和布局,使得开发者能够快速构建出与微信界面类似的移动应用。这个源码项目通常会涵盖登录注册、聊天界面、...

    微信小程序-微信小程序你的名字

    【微信小程序】是一种轻量级的应用开发平台,由腾讯公司推出,主要运行在微信环境中,无需下载安装即可使用的应用程序。它的出现使得开发者可以快速构建基于微信生态的服务和应用,为用户提供了便捷的体验。 ...

    类似微信服务器端源码

    【标题】:“类似微信服务器端源码”通常指的是一个用于构建即时通讯(Instant Messaging, IM)系统的服务器端代码,类似于微信这种大规模、高并发、实时通信的应用架构。微信作为全球最大的社交平台之一,其背后的...

    微信小程序:拼车源码行业多个源代码.rar

    可以使用微信小程序自带的全局数据管理,或者引入第三方状态管理库,如Vuex for Weapp,帮助组织和管理复杂的状态。 9. **性能优化**:为了提供流畅的用户体验,小程序开发需要注意性能优化,例如合理使用wx....

    IOS仿微信界面

    综上所述,"IOS仿微信界面"这一项目涵盖了iOS开发的众多核心技术和最佳实践,对开发者来说是一次综合性的学习和实践机会。通过这个项目,开发者可以深入理解iOS应用的架构设计、UI实现、网络通信以及用户体验等多个...

    微信小程序实现lol战绩查询weapp-lolgame-master.zip

    微信小程序是一种轻量级的应用开发平台,主要针对移动端,由腾讯公司推出,旨在提供便捷的、无需下载安装即可使用的应用体验。"微信小程序实现lol战绩查询"项目是利用微信小程序平台,开发出的一个用于查询《英雄...

    柚子门店微商城小程序 yzmdwsc_sun1.2.2安装更新一体包.zip微信小程序模板源码

    "安装更新一体包"指的是包含了安装和更新功能的完整包,用户只需一次下载,即可完成安装和后续的版本更新。这对于用户和管理员来说非常便捷,减少了手动操作的复杂性,确保了系统的稳定性和兼容性。 【主要技术栈】...

    微信小程序的vue.js版weixinSPA-master.zip

    将Vue.js应用于微信小程序,可以充分利用Vue的特性来构建微信小程序,提升开发效率和代码可维护性。 在"weixinSPA-master.zip"这个压缩包中,包含了一个使用Vue.js开发的微信小程序项目。SPA,全称为Single Page ...

    酒类商城微信小程序.rar

    微信小程序是腾讯公司推出的一种轻量级应用开发框架,它允许开发者在微信内创建原生体验的应用,无需下载安装即可使用。其核心特性包括组件化、样式、API等,具有良好的用户体验和较低的开发成本。 二、源码结构...

    微信小程序开发-移动端商城案例源码.zip

    WXSS则类似于CSS,用于定义元素的样式,但增加了微信小程序特有的特性,如相对单位rpx,以及一些定制的样式属性。 JavaScript部分是小程序的核心,负责处理业务逻辑和数据管理。微信小程序采用基于Promise的异步...

    微信小程序Demo-和风天气:天气API,设置城市-附完整源代码.rar

    3. 界面简洁美观:采用微信小程序原生组件进行界面设计,整体风格简约大方,符合用户使用习惯。 4. 数据缓存优化:为了提高用户体验,减少网络请求,本项目对天气数据进行本地缓存,避免频繁调用API。 5. 完整源码...

    思创抽奖小程序开源版v2.1.0.zip微信小程序模板源码

    这个版本号表示它是该软件的第2个主要版本,第1个次要版本,以及第0个补丁版本,意味着它可能包含了前一版本的基础功能并进行了部分改进或添加了新特性。 微信小程序是一种轻量级的应用程序,用户无需下载安装即可...

    微信小程序设计 辣椒忍者(源码).zip

    微信小程序是一种轻量级的应用开发平台,主要针对移动端,由腾讯公司推出,旨在提供便捷的、无需下载安装即可使用的应用体验。"辣椒忍者"是一个微信小程序的实例,通过源码我们可以深入理解其设计原理和实现机制。 ...

    新浪读书微信小程序.rar

    1. 微信小程序:微信小程序是腾讯公司推出的一种轻量级的应用开发框架,它允许开发者在微信环境中构建无需下载安装即可使用的应用。用户扫一扫或搜索即可打开应用,提高了用户的使用便利性。 2. 小程序架构:微信小...

    蜗牛生活服务微信小程序源码.rar

    微信小程序是一种轻量级的应用开发平台,用户无需下载安装即可在微信内使用,为用户提供便捷的生活服务。 【描述】中的".rar"后缀表明这个源码是通过RAR格式进行压缩的,RAR是一种常见的压缩文件格式,通常用于存储...

    微信小程序网上商城PHP代码(包括客户端和服务器端)

    2. **微信小程序**: 微信小程序是腾讯公司推出的一种轻量级应用开发平台,可以在微信内无需下载安装即可使用。其前端代码通常由WXML(结构层)和WXSS(样式层)编写,以及JavaScript(逻辑层)处理业务逻辑和数据...

    微信小程序寄快递小程序源码(源码+源码导入视频教程+源码导入文档教程)小程序精选源码亲测可用

    1. **微信小程序**:微信小程序是腾讯公司推出的一种轻量级的应用开发平台,无需下载安装即可在微信内使用。它基于JavaScript、WXML和WXSS三种技术栈,提供了丰富的API接口和组件,用于开发各种功能丰富的移动应用。...

    第一部分:微信网页编辑器推荐.zip微信小程序模板源码

    本压缩包“第一部分:微信网页编辑器推荐.zip”显然聚焦于微信小程序的开发,特别是网页编辑器和模板源码的应用。 微信小程序的开发涉及到前端技术栈,主要包括WXML(微信标记语言)、WXSS(微信样式语言)以及...

Global site tag (gtag.js) - Google Analytics