为了账号安全,请及时绑定邮箱和手机立即绑定

模仿ViewPager控件

标签:
Android

自定义控件是开发中经常使用的技术。系统中自带的ViewPager实现的功能有时候不能满足开发的需要,如ViewPager没有滑动图片时的动画切换效果。通过对 ViewPager的模仿和部分功能的加强,可以使学习者了解自定义ViewGroup的实现过程,以及系统动画的实现原理。


第一步:继承ViewGroup,就必须重载父类的构造方法,和onLayout()方法。首先创建一个类,起名MyViewPager,继承ViewGroup

public class MyViewPager extends ViewGroup {

private int page;//当前页的索引

private GestureDetector detector;//手势探测

private Context context;//控件创立的上下文

private MyScroller scroller;//缓慢页面切换帮助类,

private boolean isFling;//用于判断

private MyViewOnPageChangedListener listener;//页面变化监听事件

/**

*建立两个参数的构造函数,用于在布局文件中使用。在构造函数中,调用initView()方法初始化控件,创建GestureDetector对象,响应屏幕触摸事件。

*/

public MyViewPager(Context context, AttributeSet attrs) {

super(context, attrs);

this.context=context;

// TODO Auto-generated constructor stub

initView();

}

public void initView(){

scroller=new MyScroller();

detector=new GestureDetector(context,new GestureDetector.OnGestureListener(){

@Override

public boolean onDown(MotionEvent e) {

// TODO Auto-generated method stub

return false;

}


@Override

public void onShowPress(MotionEvent e) {

// TODO Auto-generated method stub

}


@Override

public boolean onSingleTapUp(MotionEvent e) {

// TODO Auto-generated method stub

return false;

}

/**

 * 图片缓慢滑动效果

 */

@Override

public boolean onScroll(MotionEvent e1, MotionEvent e2,

float distanceX, float distanceY) {

// TODO Auto-generated method stub

scrollBy((int)distanceX,0);

return false;

}


@Override

public void onLongPress(MotionEvent e) {

// TODO Auto-generated method stub

}

/**

 * 图片快速滑动切换

 */

@Override

public boolean onFling(MotionEvent e1, MotionEvent e2,

float velocityX, float velocityY) {

// TODO Auto-generated method stub

isFling=true;

if(velocityX<0&&page<getChildCount()-1){

page++;

}else if(velocityX>0&&page>0){

page--;

}

moveToDes(page);

return false;

}});

}

/** * 设置子view的布局,使其按照父控件的大小沿着水平方向展开 */


@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

// TODO Auto-generated method stub

for(int i=0;i<getChildCount();i++){

getChildAt(i).layout(i*getWidth(),0,getWidth()+i*getWidth(),getHeight());

}

}

/** * 重载onTouchEvent方法,设置page值,当手指滑动超过二分之一屏幕宽度时,切换到下一个或上一个页面, * 当不足二分之一屏幕宽度时,页面不切换 */


private int firstPosition;//记录手指按下时的位置

@Override

public boolean onTouchEvent(MotionEvent event) {

// TODO Auto-generated method stub

detector.onTouchEvent(event);

 super.onTouchEvent(event);

 

 switch (event.getAction()) {

 

case MotionEvent.ACTION_DOWN:

firstPosition=(int)event.getX();

break;

case MotionEvent.ACTION_UP:

/**

 * 用isFling区分缓慢移动和快速移动

 */

if(!isFling){

if(event.getX()-firstPosition>getWidth()/2){

page=page-1;

}else if(firstPosition-event.getX()>getWidth()/2){

page=page+1;

}

moveToDes(page);

break;

}

isFling=false;

}

 return true;

}

/**

 * 使其移动到page相应的页面

 * @param page

 */

public  void moveToDes(int page) {

// TODO Auto-generated method stub

if(page<=0){

page=0;

}

if(page>=getChildCount()-1){

page=getChildCount()-1;

}

/**

 * 迅速页面切换

 */

//scrollTo(page*getWidth(), 0);

/**

 * 添加页面变化监听,监听事件放入经常调用的方法里,显示事件的经常调用

 */

listener.onPageChanged(page);

//缓慢页面切换动画

int distance=page*getWidth()-getScrollX();

scroller.startScroll(getScrollX(), distance);

invalidate();//刷新页面,重画,并且重新执行computeScroll()

}

//重复执行该方法,实现动画效果

@Override

public void computeScroll() {

// TODO Auto-generated method stub

super.computeScroll();

if(scroller.isScrolling()){

scrollTo(scroller.getCurrentX(), 0);

invalidate();

}

}

/**

 * 设置监听事件方法

 * @param listener

 */

public void setPageChangedListener(MyViewOnPageChangedListener listener){

this.listener=listener;

}

/**

 * 监听事件接口,监听页面变化

 * @author Charles

 *

 */

interface MyViewOnPageChangedListener{

public void onPageChanged(int page);

}


}


第二步:自定义MyScroller

public class MyScroller {

public int distance;//动画运行距离

public int startX;//动画开始位置

public boolean isFinish;//判断动画是否完成

public int startTime;//动画开始时间

public int duration=500;//动画持续时间

public int currentX;//当前坐标

public void startScroll(int startX,int distance){

this.distance=distance;

this.startX=startX;

startTime=(int)SystemClock.uptimeMillis();

isFinish=false;

}

public boolean isScrolling(){

if(isFinish){

return false;

}

int lastTime=(int)SystemClock.uptimeMillis()-startTime;

if(lastTime<=duration){

currentX=startX+lastTime*distance/duration;//通过当前时间,判断当前位置

}else{

currentX=startX+distance;

isFinish=true;

}

return true;

}

public int getCurrentX(){

return currentX;

}

}

第三步:定义布局文件,将自定义的控件放到布局文件中

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    tools:context="com.example.define_ViewPager.MainActivity" >

<RadioGroup

    android:id="@+id/group"

    android:orientation="horizontal"

    android:layout_width="match_parent"

    android:layout_height="30dp"/>

    <com.example.define_ViewPager.MyViewPager

        android:id="@+id/myViewPager"

        android:layout_width="match_parent"

        android:layout_height="0dp"

        android:layout_weight="1"

        />

</LinearLayout>

第四步:在Activity中,将准备好的图片加载到MyViewPager中

public class MainActivity extends Activity {

private MyViewPager viewPager;

private RadioGroup group;//选择按钮组

private int[] images={R.drawable.a1,R.drawable.a2,R.drawable.a3

,R.drawable.a4,R.drawable.a5,R.drawable.a6};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

viewPager=(MyViewPager) findViewById(R.id.myViewPager);

group=(RadioGroup) findViewById(R.id.group);

//加载图片

for(int i=0;i<images.length;i++){

View view=new View(this);

view.setBackgroundResource(images[i]);

viewPager.addView(view);

}

//添加单选按钮到group中

for(int i=0;i<viewPager.getChildCount();i++){

RadioButton button=new RadioButton(this);

button.setId(i);

if(i==0){

button.setChecked(true);

}

group.addView(button);

}

/**

 * 设置监听方法,当页面变化时,使相应的RadioButton选中

 */

viewPager.setPageChangedListener(new MyViewOnPageChangedListener(){

@Override

public void onPageChanged(int page) {

// TODO Auto-generated method stub

RadioButton button=(RadioButton)group.getChildAt(page);

button.setChecked(true);

}});

group.setOnCheckedChangeListener(new OnCheckedChangeListener(){

@Override

public void onCheckedChanged(RadioGroup group, int checkedId) {

// TODO Auto-generated method stub

viewPager.moveToDes(checkedId);//移动到选中页

}});

}

}








原文链接:http://www.apkbus.com/blog-809108-62075.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消