当前位置: 移动技术网 > IT编程>移动开发>Android > Android编程实现小说阅读器滑动效果的方法

Android编程实现小说阅读器滑动效果的方法

2019年07月24日  | 移动技术网IT编程  | 我要评论

三对夫妻,极度神乳,辣文合集 高h

本文实例讲述了android编程实现小说阅读器滑动效果的方法。分享给大家供大家参考,具体如下:

看过小说都知道小说阅读器翻页有好多种效果,比如仿真翻页,滑动翻页,等等。由于某种原因,突然想写一个简单点的滑动翻页效果。在这里写出来也没有什么意图,希望大家可以根据这个效果举一反三,写出其他的效果。图就不上了。

下面是代码:大家理解ontouch事件即可

package com.example.testscroll.view; 
import android.content.context; 
import android.util.attributeset; 
import android.view.motionevent; 
import android.view.velocitytracker; 
import android.view.view; 
import android.view.viewconfiguration; 
import android.view.viewgroup; 
import android.widget.scroller; 
public class flipperlayout extends viewgroup { 
 private scroller mscroller; 
 private velocitytracker mvelocitytracker; 
 private int mvelocityvalue = 0; 
 /** 商定这个滑动是否有效的距离 */ 
 private int limitdistance = 0; 
 private int screenwidth = 0; 
 /** 手指移动的方向 */ 
 private static final int move_to_left = 0; 
 private static final int move_to_right = 1; 
 private static final int move_no_result = 2; 
 /** 最后触摸的结果方向 */ 
 private int mtouchresult = move_no_result; 
 /** 一开始的方向 */ 
 private int mdirection = move_no_result; 
 /** 触摸的模式 */ 
 private static final int mode_none = 0; 
 private static final int mode_move = 1; 
 private int mmode = mode_none; 
 /** 滑动的view */ 
 private view mscrollerview = null; 
 /** 最上层的view(处于边缘的,看不到的) */ 
 private view currenttopview = null; 
 /** 显示的view,显示在屏幕 */ 
 private view currentshowview = null; 
 /** 最底层的view(看不到的) */ 
 private view currentbottomview = null; 
 public flipperlayout(context context) { 
  super(context); 
  init(context); 
 } 
 public flipperlayout(context context, attributeset attrs, int defstyle) { 
  super(context, attrs, defstyle); 
  init(context); 
 } 
 public flipperlayout(context context, attributeset attrs) { 
  super(context, attrs); 
  init(context); 
 } 
 private void init(context context) { 
  mscroller = new scroller(context); 
  screenwidth = context.getresources().getdisplaymetrics().widthpixels; 
  limitdistance = screenwidth / 3; 
 } 
 /*** 
  * 
  * @param listener 
  * @param currentbottomview 
  *  最底层的view,初始状态看不到 
  * @param currentshowview 
  *  正在显示的view 
  * @param currenttopview 
  *  最上层的view,初始化时滑出屏幕 
  */ 
 public void initflipperviews(touchlistener listener, view currentbottomview, view currentshowview, view currenttopview) { 
  this.currentbottomview = currentbottomview; 
  this.currentshowview = currentshowview; 
  this.currenttopview = currenttopview; 
  settouchresultlistener(listener); 
  addview(currentbottomview); 
  addview(currentshowview); 
  addview(currenttopview); 
  /** 默认将最上层的view滑动的边缘(用于查看上一页) */ 
  currenttopview.scrollto(-screenwidth, 0); 
 } 
 @override 
 protected void onlayout(boolean changed, int l, int t, int r, int b) { 
  for (int i = 0; i < getchildcount(); i++) { 
   view child = getchildat(i); 
   int height = child.getmeasuredheight(); 
   int width = child.getmeasuredwidth(); 
   child.layout(0, 0, width, height); 
  } 
 } 
 @override 
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { 
  super.onmeasure(widthmeasurespec, heightmeasurespec); 
  int width = measurespec.getsize(widthmeasurespec); 
  int height = measurespec.getsize(heightmeasurespec); 
  setmeasureddimension(width, height); 
  for (int i = 0; i < getchildcount(); i++) { 
   getchildat(i).measure(widthmeasurespec, heightmeasurespec); 
  } 
 } 
 private int startx = 0; 
 @override 
 public boolean dispatchtouchevent(motionevent ev) { 
  switch (ev.getaction()) { 
  case motionevent.action_down: 
   if (!mscroller.isfinished()) { 
    break; 
   } 
   startx = (int) ev.getx(); 
   break; 
  } 
  return super.dispatchtouchevent(ev); 
 } 
 @suppresswarnings("deprecation") 
 @override 
 public boolean ontouchevent(motionevent event) { 
  obtainvelocitytracker(event); 
  switch (event.getaction()) { 
  case motionevent.action_move: 
   if (!mscroller.isfinished()) { 
    return super.ontouchevent(event); 
   } 
   if (startx == 0) { 
    startx = (int) event.getx(); 
   } 
   final int distance = startx - (int) event.getx(); 
   if (mdirection == move_no_result) { 
    if (mlistener.whetherhasnextpage() && distance > 0) { 
     mdirection = move_to_left; 
    } else if (mlistener.whetherhaspreviouspage() && distance < 0) {
     mdirection = move_to_right; 
    } 
   } 
   if (mmode == mode_none 
     && ((mdirection == move_to_left && mlistener.whetherhasnextpage()) || (mdirection == move_to_right && mlistener 
       .whetherhaspreviouspage()))) { 
    mmode = mode_move; 
   } 
   if (mmode == mode_move) { 
    if ((mdirection == move_to_left && distance <= 0) || (mdirection == move_to_right && distance >= 0)) { 
     mmode = mode_none; 
    } 
   } 
   if (mdirection != move_no_result) { 
    if (mdirection == move_to_left) { 
     if (mscrollerview != currentshowview) { 
      mscrollerview = currentshowview; 
     } 
    } else { 
     if (mscrollerview != currenttopview) { 
      mscrollerview = currenttopview; 
     } 
    } 
    if (mmode == mode_move) { 
     mvelocitytracker.computecurrentvelocity(1000, viewconfiguration.getmaximumflingvelocity()); 
     if (mdirection == move_to_left) { 
      mscrollerview.scrollto(distance, 0); 
     } else { 
      mscrollerview.scrollto(screenwidth + distance, 0); 
     } 
    } else { 
     final int scrollx = mscrollerview.getscrollx(); 
     if (mdirection == move_to_left && scrollx != 0 && mlistener.whetherhasnextpage()) { 
      mscrollerview.scrollto(0, 0); 
     } else if (mdirection == move_to_right && mlistener.whetherhaspreviouspage() && screenwidth != math.abs(scrollx)) { 
      mscrollerview.scrollto(-screenwidth, 0); 
     } 
    } 
   } 
   break; 
  case motionevent.action_up: 
   if (mscrollerview == null) { 
    return super.ontouchevent(event); 
   } 
   final int scrollx = mscrollerview.getscrollx(); 
   mvelocityvalue = (int) mvelocitytracker.getxvelocity(); 
   // scroll左正,右负(),(startx + dx)的值如果为0,即复位 
   /* 
    * android.widget.scroller.startscroll( int startx, int starty, int 
    * dx, int dy, int duration ) 
    */ 
   int time = 500; 
   if (mmode == mode_move && mdirection == move_to_left) { 
    if (scrollx > limitdistance || mvelocityvalue < -time) { 
     // 手指向左移动,可以翻屏幕 
     mtouchresult = move_to_left; 
     if (mvelocityvalue < -time) { 
      time = 200; 
     } 
     mscroller.startscroll(scrollx, 0, screenwidth - scrollx, 0, time); 
    } else { 
     mtouchresult = move_no_result; 
     mscroller.startscroll(scrollx, 0, -scrollx, 0, time); 
    } 
   } else if (mmode == mode_move && mdirection == move_to_right) { 
    if ((screenwidth - scrollx) > limitdistance || mvelocityvalue > time) { 
     // 手指向右移动,可以翻屏幕 
     mtouchresult = move_to_right; 
     if (mvelocityvalue > time) { 
      time = 250; 
     } 
     mscroller.startscroll(scrollx, 0, -scrollx, 0, time); 
    } else { 
     mtouchresult = move_no_result; 
     mscroller.startscroll(scrollx, 0, screenwidth - scrollx, 0, time); 
    } 
   } 
   resetvariables(); 
   postinvalidate(); 
   break; 
  } 
  return true; 
 } 
 private void resetvariables() { 
  mdirection = move_no_result; 
  mmode = mode_none; 
  startx = 0; 
  releasevelocitytracker(); 
 } 
 private touchlistener mlistener; 
 private void settouchresultlistener(touchlistener listener) { 
  this.mlistener = listener; 
 } 
 @override 
 public void computescroll() { 
  super.computescroll(); 
  if (mscroller.computescrolloffset()) { 
   mscrollerview.scrollto(mscroller.getcurrx(), mscroller.getcurry());
   postinvalidate(); 
  } else if (mscroller.isfinished() && mlistener != null && mtouchresult != move_no_result) { 
   if (mtouchresult == move_to_left) { 
    if (currenttopview != null) { 
     removeview(currenttopview); 
    } 
    currenttopview = mscrollerview; 
    currentshowview = currentbottomview; 
    if (mlistener.currentislastpage()) { 
     final view newview = mlistener.createview(mtouchresult); 
     currentbottomview = newview; 
     addview(newview, 0); 
    } else { 
     currentbottomview = new view(getcontext()); 
     currentbottomview.setvisibility(view.gone); 
     addview(currentbottomview, 0); 
    } 
   } else { 
    if (currentbottomview != null) { 
     removeview(currentbottomview); 
    } 
    currentbottomview = currentshowview; 
    currentshowview = mscrollerview; 
    if (mlistener.currentisfirstpage()) { 
     final view newview = mlistener.createview(mtouchresult); 
     currenttopview = newview; 
     currenttopview.scrollto(-screenwidth, 0); 
     addview(currenttopview); 
    } else { 
     currenttopview = new view(getcontext()); 
     currenttopview.scrollto(-screenwidth, 0); 
     currenttopview.setvisibility(view.gone); 
     addview(currenttopview); 
    } 
   } 
   mtouchresult = move_no_result; 
  } 
 } 
 private void obtainvelocitytracker(motionevent event) { 
  if (mvelocitytracker == null) { 
   mvelocitytracker = velocitytracker.obtain(); 
  } 
  mvelocitytracker.addmovement(event); 
 } 
 private void releasevelocitytracker() { 
  if (mvelocitytracker != null) { 
   mvelocitytracker.recycle(); 
   mvelocitytracker = null; 
  } 
 } 
 /*** 
  * 用来实时回调触摸事件回调 
  * 
  * @author freeson 
  */ 
 public interface touchlistener { 
  /** 手指向左滑动,即查看下一章节 */ 
  final int move_to_left = 0; 
  /** 手指向右滑动,即查看上一章节 */ 
  final int move_to_right = 1; 
  /** 
   * 创建一个承载text的view 
   * 
   * @param direction 
   *   {@link move_to_left,move_to_right} 
   * @return 
   */ 
  public view createview(final int direction); 
  /*** 
   * 当前页是否是第一页 
   * 
   * @return 
   */ 
  public boolean currentisfirstpage(); 
  /*** 
   * 当前页是否是最后一页 
   * 
   * @return 
   */ 
  public boolean currentislastpage(); 
  /** 
   * 当前页是否有上一页(用来判断可滑动性) 
   * 
   * @return 
   */ 
  public boolean whetherhaspreviouspage(); 
  /*** 
   * 当前页是否有下一页(用来判断可滑动性) 
   * 
   * @return 
   */ 
  public boolean whetherhasnextpage(); 
 } 
}

activity测试文件:

package com.example.testscroll; 
import java.io.bytearrayoutputstream; 
import java.io.ioexception; 
import java.io.inputstream; 
import android.app.activity; 
import android.content.res.assetmanager; 
import android.os.bundle; 
import android.os.handler; 
import android.view.layoutinflater; 
import android.view.view; 
import android.view.view.onclicklistener; 
import android.widget.textview; 
import com.example.testscroll.view.flipperlayout; 
import com.example.testscroll.view.flipperlayout.touchlistener; 
import com.example.testscrollactivity.r; 
public class mainactivity extends activity implements onclicklistener, touchlistener { 
 private string text = ""; 
 private int textlenght = 0; 
 private static final int count = 400; 
 private int currenttopendindex = 0; 
 private int currentshowendindex = 0; 
 private int currentbottomendindex = 0; 
 private handler handler = new handler() { 
  public void handlemessage(android.os.message msg) { 
   flipperlayout rootlayout = (flipperlayout) findviewbyid(r.id.container); 
   view recoverview = layoutinflater.from(mainactivity.this).inflate(r.layout.view_new, null); 
   view view1 = layoutinflater.from(mainactivity.this).inflate(r.layout.view_new, null); 
   view view2 = layoutinflater.from(mainactivity.this).inflate(r.layout.view_new, null); 
   rootlayout.initflipperviews(mainactivity.this, view2, view1, recoverview); 
   textlenght = text.length(); 
   system.out.println("----textlenght----->" + textlenght); 
   textview textview = (textview) view1.findviewbyid(r.id.textview); 
   if (textlenght > count) { 
    textview.settext(text.subsequence(0, count)); 
    textview = (textview) view2.findviewbyid(r.id.textview); 
    if (textlenght > (count << 1)) { 
     textview.settext(text.subsequence(count, count * 2)); 
     currentshowendindex = count; 
     currentbottomendindex = count << 1; 
    } else { 
     textview.settext(text.subsequence(count, textlenght)); 
     currentshowendindex = textlenght; 
     currentbottomendindex = textlenght; 
    } 
   } else { 
    textview.settext(text.subsequence(0, textlenght)); 
    currentshowendindex = textlenght; 
    currentbottomendindex = textlenght; 
   } 
  }; 
 }; 
 @override 
 protected void oncreate(bundle savedinstancestate) { 
  super.oncreate(savedinstancestate); 
  setcontentview(r.layout.activity_main); 
  new readingthread().start(); 
 } 
 @override 
 public void onclick(view v) { 
 } 
 @override 
 public view createview(final int direction) { 
  string txt = ""; 
  if (direction == touchlistener.move_to_left) { 
   currenttopendindex = currentshowendindex; 
   final int nextindex = currentbottomendindex + count; 
   currentshowendindex = currentbottomendindex; 
   if (textlenght > nextindex) { 
    txt = text.substring(currentbottomendindex, nextindex); 
    currentbottomendindex = nextindex; 
   } else { 
    txt = text.substring(currentbottomendindex, textlenght); 
    currentbottomendindex = textlenght; 
   } 
  } else { 
   currentbottomendindex = currentshowendindex; 
   currentshowendindex = currenttopendindex; 
   currenttopendindex = currenttopendindex - count; 
   txt = text.substring(currenttopendindex - count, currenttopendindex); 
  } 
  view view = layoutinflater.from(this).inflate(r.layout.view_new, null); 
  textview textview = (textview) view.findviewbyid(r.id.textview); 
  textview.settext(txt); 
  system.out.println("-top->" + currenttopendindex + "-show->" + currentshowendindex + "--bottom-->" + currentbottomendindex); 
  return view; 
 } 
 @override 
 public boolean whetherhaspreviouspage() { 
  return currentshowendindex > count; 
 } 
 @override 
 public boolean whetherhasnextpage() { 
  return currentshowendindex < textlenght; 
 } 
 @override 
 public boolean currentisfirstpage() { 
  boolean should = currenttopendindex > count; 
  if (!should) { 
   currentbottomendindex = currentshowendindex; 
   currentshowendindex = currenttopendindex; 
   currenttopendindex = currenttopendindex - count; 
  } 
  return should; 
 } 
 @override 
 public boolean currentislastpage() { 
  boolean should = currentbottomendindex < textlenght; 
  if (!should) { 
   currenttopendindex = currentshowendindex; 
   final int nextindex = currentbottomendindex + count; 
   currentshowendindex = currentbottomendindex; 
   if (textlenght > nextindex) { 
    currentbottomendindex = nextindex; 
   } else { 
    currentbottomendindex = textlenght; 
   } 
  } 
  return should; 
 } 
 private class readingthread extends thread { 
  public void run() { 
   assetmanager am = getassets(); 
   inputstream response; 
   try { 
    response = am.open("text.txt"); 
    if (response != null) { 
     bytearrayoutputstream baos = new bytearrayoutputstream(); 
     int i = -1; 
     while ((i = response.read()) != -1) { 
      baos.write(i); 
     } 
     text = new string(baos.tobytearray(), "utf-8"); 
     baos.close(); 
     response.close(); 
     handler.sendemptymessage(0); 
    } 
   } catch (ioexception e) { 
    e.printstacktrace(); 
   } 
  } 
 } 
}

xml布局文件:

<?xml version="1.0" encoding="utf-8"?> 
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 android:orientation="horizontal" > 
 <textview 
  android:id="@+id/textview" 
  android:layout_width="0dp" 
  android:layout_height="match_parent" 
  android:layout_weight="1.0" 
  android:background="#666666" 
  android:gravity="center" 
  android:text="新建的view" 
  android:textcolor="@android:color/white" 
  android:textsize="16sp" 
  android:visibility="visible" /> 
 <view 
  android:layout_width="5dp" 
  android:layout_height="match_parent" 
  android:background="#ffff00" 
  android:gravity="center" 
  android:textsize="25sp" 
  android:visibility="visible" />
</linearlayout>

activity布局文件:

<com.example.testscroll.view.flipperlayout xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:tools="http://schemas.android.com/tools" 
 android:id="@+id/container" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" > 
</com.example.testscroll.view.flipperlayout>

备注:上面为什么加一个速率计算器呢,其实只是为了识别这个动作是不是快速滑动的动作,就算滑动的距离不到屏幕的1/3,但是只要速率满足都可以判定改滑动是一个翻页的动作。

注意哦:这只是其中一个滑动的效果而已啊,不包括小说分章节的逻辑哦。虽然有些粗糙,但是还是有可以值得学习的地方,大家如果还有什么好的解决方案,可以一起讨论。

附上demo下载地址 。

希望本文所述对大家android程序设计有所帮助。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网