我们第一次进入一款应用的时候经常会出现一个导航动画,一般都是四张或者五张图片,大体就是介绍这个应用的功能,那么这个导航动画该如何实现呢。其实实现的方式有很多种,最简单也是最暴力的一种就是新建四个或者五个activity,然后捕捉滑动事件来回跳转就行了。这个方法是我刚学android的时候看黑马android视频的时候学的。虽然可以实现,但是感觉太过麻烦。今天我介绍的这两种呢,一个是用ViewFlipper实现的,另一个使用ViewPager实现的。
首先来说第一种方式ViewFlipper,ViewFlipper是继承自FrameLayout的,所以它的使用方式,就是把n张图片都堆叠在ViewFlipper中,通过滑动就可以看到下一层的图片。下面是布局文件代码
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
android:id="@+id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:persistentDrawingCache="animation" >
android:id="@+id/first"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
android:id="@+id/firstIV"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:src="@drawable/view1" />
android:id="@+id/second"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
android:id="@+id/secondIV"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:src="@drawable/view2" />
android:id="@+id/third"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
android:id="@+id/thirdIV"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:src="@drawable/view3" />
android:id="@+id/fourth"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
android:id="@+id/fourthIV"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:src="@drawable/view4" />
android:id="@+id/endIV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="100dp"
android:src="@drawable/enter" />
我在上述布局文件中放了四张图片和一个图片按钮。
下面说一下java文件中应该如何写
首先在oncrete中获取控件,由于前四张图片不需要做任何处理,所以不获取前四张图片了。只获取了最后一个图片按钮用来跳转的。
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.view_flipper);
initView();
endIV.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(ViewFlipperActivity.this,
HomePageActivity.class);
startActivity(intent);
finish();
}
});
}
private void initView() {
// TODO Auto-generated method stub
flipper = (ViewFlipper) findViewById(R.id.flipper);
endIV = (ImageView) findViewById(R.id.endIV);
detector = new GestureDetector(this);
}
剩下的就是关于滑动事件的处理了,滑动事件处理用到了GestureDetector。所以要写一个OnGestureListener的监听器,用一个类实现这个接口后,会有好几个未实现的方法。我们只需要关注onFling方法就够了
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// TODO Auto-generated method stub
if (e1.getX() - e2.getX() > 120) {
this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_in));
this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_out));
if (flipper.getCurrentView().getId() != R.id.fourth)
this.flipper.showNext();
return true;
} else if (e1.getX() - e2.getX() < -120) {
this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_in));
this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_out));
if (flipper.getCurrentView().getId() != R.id.first)
this.flipper.showPrevious();
return true;
}
return false;
}
滑动的时候用到了四个动画进行切换,动画这部分很简单,就不再粘贴代码。
最后记得重写onTouch事件
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
return detector.onTouchEvent(event);
}
这样就结束了。下面是效果图。
第二种方法是用ViewPager和fragment搭配来实现导航动画,这种方式也是我最满意的一直方式。它比ViewFlipper的优势在于不用自己写动画效果,而且图片间的切换效果要比ViewFlipper好很多。
布局文件很简单
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/view_pager" />
java文件
@Override
protected void onCreate(Bundle arg0) {
// TODO Auto-generated method stub
super.onCreate(arg0);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.first_page);
mViewPager = (ViewPager) findViewById(R.id.view_pager);
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
super.onPageSelected(position);
}
});
mAdapter = new PagerAdapter(this);
ImageViewFragment imageViewFragment1 = new ImageViewFragment(
R.drawable.view1, NO_BTN);
ImageViewFragment imageViewFragment2 = new ImageViewFragment(
R.drawable.view2, NO_BTN);
ImageViewFragment imageViewFragment3 = new ImageViewFragment(
R.drawable.view3, NO_BTN);
ImageViewFragment imageViewFragment4 = new ImageViewFragment(
R.drawable.view4, R.drawable.enter);
mAdapter.addTabs(imageViewFragment1, null);
mAdapter.addTabs(imageViewFragment2, null);
mAdapter.addTabs(imageViewFragment3, null);
mAdapter.addTabs(imageViewFragment4, null);
mViewPager.setAdapter(mAdapter);
}
其中PagerAdapter是自己重写的,要注意和系统的区分。ImageViewFragment也是自己重写的,ImageViewFragment通过接受不同的drawable参数来改变背景图片。
ImageViewFragment代码
public static class ImageViewFragment extends Fragment {
private final int mbg;
private final int mbtn;
public ImageViewFragment(int bgID, int btnID) {
mbg = bgID;
mbtn = btnID;
}
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.imagelayout, null);
ImageView bgIV = (ImageView) view.findViewById(R.id.bgIV);
bgIV.setImageResource(mbg);
if(mbtn!=NO_BTN){
ImageView btnIV=(ImageView) view.findViewById(R.id.endIV);
btnIV.setImageResource(mbtn);
btnIV.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent(getActivity(),HomePage.class);
startActivity(intent);
getActivity().finish();
}
});
}
return view;
}
PagerAdapter代码
public static class PagerAdapter extends FragmentPagerAdapter {
private final Context mContext;
private final ArrayList mTabs = new ArrayList();
public PagerAdapter(FragmentActivity activity) {
super(activity.getSupportFragmentManager());
mContext = activity;
}
static final class TabInfo {
private final ImageViewFragment mIVF;
private final Bundle mArgs;
public TabInfo(ImageViewFragment aIVF, Bundle args) {
// TODO Auto-generated constructor stub
mIVF = aIVF;
mArgs = args;
}
}
@Override
public Fragment getItem(int position) {
// TODO Auto-generated method stub
TabInfo info = mTabs.get(position);
return info.mIVF;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mTabs.size();
}
public void addTabs(ImageViewFragment IVF, Bundle args) {
TabInfo info = new TabInfo(IVF, args);
mTabs.add(info);
notifyDataSetChanged();
}
}
第二种也完成了,下面看看效果图吧,注意和第一种的效果图进行对比