Android自定义左右或上下滑动翻页效果

 更新时间:2022年05月10日 08:19:44   作者:漫不_经心  
这篇文章主要为大家详细介绍了Android自定义左右或上下滑动翻页效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android自定义左右或上下滑动翻页展示的具体代码,供大家参考,具体内容如下

该自定义的效果和ViewPage+Fragment差不多

上下滑动翻页,继承ScrollView

public class SlideScrollView extends ScrollView implements PageSlide{ 
 private TotalSlide totalSlide; 
 public SlideScrollView(AppCompatActivity context) { 
 super(context); 
 try { 
  totalSlide=new TotalSlide(this,context); 
 } catch (NoSuchMethodException e) { 
  e.printStackTrace(); 
 } 
 totalSlide.init(context); 
 totalSlide.linearLayout.setOrientation(totalSlide.linearLayout.VERTICAL); 
 this.setLayoutParams(totalSlide.params); 
 this.setVerticalScrollBarEnabled(false); 
 this.addView(totalSlide.linearLayout); 
 } 
 public float getScroll() { 
 return super.getScrollY(); 
 } 
 public void setScroll(Integer value) { 
 super.setScrollY(value); 
 } 
 @Override 
 public boolean onTouchEvent(MotionEvent ev) { 
 try { 
  return totalSlide.MyTouchEvent(ev); 
 } catch (InvocationTargetException e) { 
  e.printStackTrace(); 
 } catch (IllegalAccessException e) { 
  e.printStackTrace(); 
 } 
 return TouchEvent(ev); 
 } 
 public boolean TouchEvent(MotionEvent ev){ 
 return super.onTouchEvent(ev); 
 } 
 public TotalSlide getTotalSlide(){ 
 return this.totalSlide; 
 } 
} 

左右滑动翻页,继承HorizontalScrollView

public class SlideHorizontalScrollView extends HorizontalScrollView implements PageSlide{ 
 private TotalSlide totalSlide; 
 public SlideHorizontalScrollView(AppCompatActivity context){ 
  super(context); 
  try { 
   totalSlide=new TotalSlide(this,context); 
  } catch (NoSuchMethodException e) { 
   e.printStackTrace(); 
  } 
  totalSlide.init(context); 
  totalSlide.linearLayout.setOrientation(totalSlide.linearLayout.HORIZONTAL); 
  this.setLayoutParams(totalSlide.params); 
  this.setHorizontalScrollBarEnabled(false); 
  this.addView(totalSlide.linearLayout); 
 } 
 public float getScroll() { 
  return getScrollX(); 
 } 
 public void setScroll(Integer value) { 
  setScrollX(value); 
 } 
 @Override 
 public boolean onTouchEvent(MotionEvent ev) { 
  try { 
   return totalSlide.MyTouchEvent(ev); 
  } catch (InvocationTargetException e) { 
   e.printStackTrace(); 
  } catch (IllegalAccessException e) { 
   e.printStackTrace(); 
  } 
  return TouchEvent(ev); 
 } 
 public boolean TouchEvent(MotionEvent ev){ 
  return super.onTouchEvent(ev); 
 } 
 public TotalSlide getTotalSlide(){ 
  return this.totalSlide; 
 } 
} 

下面的是两种翻页的底层

package com.hy.View; 
 
import android.os.Handler; 
import android.support.annotation.LayoutRes; 
import android.support.v7.app.AppCompatActivity; 
import android.util.DisplayMetrics; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.WindowManager; 
import android.widget.LinearLayout; 
 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.util.ArrayList; 
import java.util.List; 
 
/** 
 * 作用:实现上下左右滑动翻页,效果如 微信左右滑动效果 
 */ 
 
public interface PageSlide { 
 public TotalSlide getTotalSlide(); 
 public boolean TouchEvent(MotionEvent ev); 
 public float getScroll(); 
 public void setScroll(Integer value); 
 class TotalSlide{ 
  /** 
   * 设置翻页速度 
   * @param speed 速度,默认为20 
   */ 
  public void setSpeed(float speed){ 
   this.speed=speed; 
  } 
  TotalSlide(PageSlide pageSlide,AppCompatActivity context) throws NoSuchMethodException { 
   this.pageSlide=pageSlide; 
   this.context=context; 
   WindowManager wm = context.getWindowManager(); 
   if(pageSlide instanceof SlideHorizontalScrollView){ 
    fill = wm.getDefaultDisplay().getWidth(); 
    get=pageSlide.getClass().getMethod("getScroll"); 
    set=pageSlide.getClass().getMethod("setScroll",Integer.class); 
    //Toast.makeText(context,"TotalSlide:"+get.getName(),Toast.LENGTH_LONG).show(); 
   }else if(pageSlide instanceof SlideScrollView){ 
    fill = wm.getDefaultDisplay().getHeight(); 
    get=pageSlide.getClass().getMethod("getScroll"); 
    set=pageSlide.getClass().getMethod("setScroll",Integer.class); 
   } 
  } 
  //初始化 
  void init(AppCompatActivity context){ 
   DisplayMetrics metrics = new DisplayMetrics(); 
   context.getWindowManager().getDefaultDisplay().getMetrics(metrics); 
   params = new LinearLayout.LayoutParams(metrics.widthPixels, metrics.heightPixels); 
   linearLayout = new LinearLayout(context); 
   linearLayout.setLayoutParams(params); 
  } 
  /** 
   * 增加页面 
   * @param layout 该页面的布局文件 
   * @param myAppCompatActivity 该布局文件的java文件 
   */ 
  public void addPage(@LayoutRes int layout, MyAppCompatActivity myAppCompatActivity){ 
   View view=context.getLayoutInflater().inflate(layout,null); 
   myAppCompatActivity.view=view; 
   myAppCompatActivity.context=context; 
   myAppCompatActivity.onCreate(); 
   insertPage(view); 
  } 
  /** 
   * 增加页面 
   * @param layout 该页面的布局文件 
   */ 
  public void addPage(@LayoutRes int layout){ 
   View view=context.getLayoutInflater().inflate(layout,null); 
   insertPage(view); 
  } 
  /** 
   * 增加页面 
   * @param myAppCompatActivity 该布局文件的java文件 
   */ 
  public void addPage(MyAppCompatActivity myAppCompatActivity){ 
   View view=new View(context); 
   myAppCompatActivity.view=view; 
   myAppCompatActivity.context=context; 
   myAppCompatActivity.onCreate(); 
   insertPage(view); 
  } 
  /** 
   * 切换页面 
   * @param pageNo 切换页面的下标 
   */ 
  public void changePage(int pageNo) { 
   if(pageNo<pageList.size()&&pageNo>=0){ 
    now=fill*pageNo; 
    try { 
     set.invoke(pageSlide,(int)now); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
    } 
    this.pageNo=pageNo; 
   } 
  } 
 
  /** 
  * @return 返回当前页面编号 
  */ 
  public int getPageNo(){ 
   return pageNo; 
  } 
  /** 
   * 删除页面 
   * @param pageNo 删除页面的下标 
   */ 
  public void removePage(int pageNo) { 
   if (pageNo < pageList.size() && pageNo >= 0) { 
    linearLayout.removeView(pageList.get(pageNo)); 
    pageList.remove(pageNo); 
   } 
  } 
  /**********************************************************************************************/ 
  //展示页面的Activity 
  private AppCompatActivity context; 
  //转换页面的速度,默认为20 
  private float speed=20; 
  //当前Activity的页面滑动值倍数 
  private float fill; 
  //当前页面 
  private int pageNo=0; 
  //当前滚动条的位置 
  private float now=0; 
  //手指点击的位置 
  private float Down=0; 
  //手指松开的位置 
  private float Up=0; 
  //滑动方向 
  private float value=0; 
  //是否为第一次点击 
  private boolean b=true; 
  //页面集合 
  private List<View> pageList=new ArrayList<>(); 
  //辅助线程执行 
  private Handler handler=new Handler(); 
  //get方法 
  private Method get; 
  //get方法 
  private Method set; 
  //本页布局控件 
  LinearLayout linearLayout; 
  //页面大小 
  LinearLayout.LayoutParams params; 
  //多态 
  private PageSlide pageSlide; 
  //简化代码 
  private void insertPage(View view){ 
   view.setLayoutParams(params); 
   pageList.add(view); 
   linearLayout.addView(view); 
  } 
  //滑动线程 
  private Runnable runnable=new Runnable() { 
   @Override 
   public void run() { 
    try { 
     if((b&&(float)get.invoke(pageSlide)>=now)||(!b&&(float)get.invoke(pageSlide)<=now)){ 
      set.invoke(pageSlide,(int) (now-value)); 
      b=true; 
      handler.removeCallbacks(runnable); 
     }else{ 
      handler.postDelayed(runnable,1); 
     } 
     if(now==0&&value>0) { 
      set.invoke(pageSlide,(int)((float)get.invoke(pageSlide))); 
     }else{ 
      set.invoke(pageSlide,(int)((float)get.invoke(pageSlide)+value)); 
     } 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
    } 
   } 
  }; 
  //手指判断 
  public boolean MyTouchEvent(MotionEvent ev) throws InvocationTargetException, IllegalAccessException { 
   if(b){ 
    Down=(float)get.invoke(pageSlide); 
    b=false; 
   } 
   if(ev.getAction()==MotionEvent.ACTION_UP){ 
    Up=(float)get.invoke(pageSlide); 
    value=Up>Down?Up-Down:Down-Up; 
    b=Up>Down?true:false; 
    if(value>250){ 
     value=b?speed:-speed; 
     now=b?now+fill:now-fill; 
     pageNo= (int) (now/fill); 
     handler.post(runnable); 
    }else{ 
     value=b?-speed:speed; 
     handler.post(runnable); 
    } 
    return false; 
   } 
   return pageSlide.TouchEvent(ev); 
  } 
 } 
} 

最后还需要一个类似于碎片一样的东西

package com.hy.View; 
 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
 
/** 
 * 分页面的java类继承此类 取代AppCompatActivity 
 */ 
 
public abstract class MyAppCompatActivity { 
 /** 
 * 当作 this 来用 
 */ 
 public AppCompatActivity context; 
 /** 
 * 当前页面的根布局 用它使用 findViewById() 找控件 
 */ 
 public View view; 
 /** 
 * 初始值在这里面定义 
 */ 
 public abstract void onCreate(); 
} 

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

相关文章

  • Android动态加载布局实现技巧介绍

    Android动态加载布局实现技巧介绍

    通过使用LayoutInflater 每次点击按钮时候去读取布局文件,然后找到布局文件里面的各个VIEW 操作完VIEW 后加载进我们setContentView 方面里面的要放的布局文件里面,每次动态加载文件必需调用 removeAllViews方法,清除之前的加载进来的View
    2022-12-12
  • android实现音乐跳动效果的示例代码

    android实现音乐跳动效果的示例代码

    这篇文章主要介绍了android实现音乐跳动效果的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Android应用程序中读写txt文本文件的基本方法讲解

    Android应用程序中读写txt文本文件的基本方法讲解

    这篇文章主要介绍了Android应用程序中读写txt文本文件的基本方法讲解,基本上依靠context.openFileInput()和context.openFileOutput()两个方法为主,需要的朋友可以参考下
    2016-04-04
  • Android 实现永久保存数据的方法详解

    Android 实现永久保存数据的方法详解

    本篇文章是对Android实现永久保存数据的方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • 详解Android Bitmap的常用压缩方式

    详解Android Bitmap的常用压缩方式

    这篇文章主要介绍了详解Android Bitmap的常用压缩方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • 关于Android输入法弹窗bug的优雅处理

    关于Android输入法弹窗bug的优雅处理

    在Android应用中,当跳转到某个Activity时,该Activity显示页面的EditText获得焦点,在某些机器中会触发软键盘的自动弹出,这篇文章主要给大家介绍了关于Android输入法弹窗bug的优雅处理,需要的朋友可以参考下
    2021-10-10
  • Android实现图片叠加效果的两种方法

    Android实现图片叠加效果的两种方法

    这篇文章主要介绍了Android实现图片叠加效果的两种方法,结合实例形式分析了Android实现图片叠加效果的两种操作方法与相关注意事项,需要的朋友可以参考下
    2016-08-08
  • Android中简单的电话管理与短信管理App编写实例

    Android中简单的电话管理与短信管理App编写实例

    这篇文章主要介绍了Android中简单的电话管理与短信管理App编写实例,包括监听电话的呼叫状态以及短信群发联系人选择等基本功能的实现,代码突出要点,需要的朋友可以参考下
    2016-04-04
  • Android添加音频的几种方法

    Android添加音频的几种方法

    今天小编就为大家分享一篇关于Android添加音频的几种方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02
  • 使用RecyclerView实现瀑布流高度自适应

    使用RecyclerView实现瀑布流高度自适应

    这篇文章主要为大家详细介绍了使用RecyclerView实现瀑布流高度自适应,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09

最新评论