37 阅读器翻阅效果 viewGroup

---------------------------main.java----------------------------------

package com.example.likereadert1;

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.util.Log;

import android.view.LayoutInflater;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.TextView;

import com.example.likereadert1.FlipperLayout;

import com.example.likereadert1.FlipperLayout.TouchListener;

import com.example.likereadert1.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);

Log.i("maina", "----textLenght----->" + textLenght + "llllllllllllll");

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 {

@Override

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();

}

}

}

}

-----------------------------FlipperLayout.java---------------------------------------

package com.example.likereadert1;

import android.content.Context;

import android.util.AttributeSet;

import android.util.Log;

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);

Log.i("maina", (mListener == null) + "llllllllllllll");

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) {

//Log.i("maina", (mListener == null) + "llllllllllllll");

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();

}

}

...。。。。。。。。。。。。main.xml。。。。。。。。。。。。。

<com.example.likereadert1.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.likereadert1.FlipperLayout>

。。。。。。。。。。。flipperlayout.xml。。。。。。。。。。。。

<com.example.likereadert1.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.likereadert1.flipperlayout>

。。。。。。。。。。。。view_new.xml。。。。。。。。。。。。。

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

android:layout_width="fill_parent"

android:layout_height="fill_parent" >

<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" >

</TextView>

<View

android:layout_width="5dp"

android:layout_height="match_parent"

android:background="#FFFF00"

android:gravity="center"

android:textSize="25sp"

android:visibility="visible" />

</LinearLayout>

、、、、、、、、、、、、、、、、、其中assets文件夹下的text.txt的文件内容随便

注意xml文件里面的大小写!!!!!!!!!!!

时间: 2024-10-16 09:22:22

37 阅读器翻阅效果 viewGroup的相关文章

基于Android小说阅读器滑动效果的一种实现

看过小说都知道小说阅读器翻页有好多种效果,比如仿真翻页,滑动翻页,等等.由于某种原因,突然想写一个简单点的滑动翻页效果.在这里写出来也没有什么意图,希望大家可以根据这个效果举一反三,写出其他的效果.图就不上了. 下面是代码:大家理解onTouch事件即可 package com.example.testscroll.view; import android.content.Context; import android.util.AttributeSet; import android.view

手机版轻快PDF阅读器使用的方法

现在我们生活处处都需要手机,手机就是个移动的银行.电脑.有的人还是利用手机来进行工作的,那么如果手机接收到PDF文件,我们就需要使用手机版的PDF阅读器了,那么手机版的阅读器的使用方法是什么呢?下面就让小编来给大家介绍它的使用方法! 轻快PDF阅读器APP是一款新的小巧的PDF阅读器,适用于安卓设备,可以随时随地查看.注释和保护PDF文件.这款软件体积小.启动速度快,十分轻巧且占用内存极少:一键锁屏.夜间阅读,随心调整亮度:自动提取文档目录,一键添加书签阅读:自动定位本地文档,操作简单设计大方:

webApp 阅读器项目实践

这是一个webApp 阅读器的项目,是慕课网的老师讲授的一个实战,先给出项目源码在GitHub的地址:https://github.com/yulifromchina/MobileWebReader. 项目属于麻雀虽小,但五脏俱全的类型,对于前端新手来说,还是很有学习价值. 一.项目成果展示 二.项目所用技术 语言:Html,css,js 插件: zepto.js: 使用于移动端的js库,语法与jquery相似,但增加了触摸等移动端事件,去掉了对浏览器兼容的代码,因此更轻量级 jquery.ba

自定义日志阅读器——包括了一个load取Tomcat日志的分析器

最近在写往公司产品里添加Tomcat适配器,以支持Tomcat.有一些功能需要摘取到Tomcat的部分日志.没有合适的工具,也不想去网上找了,就自己写了一个. 简单的画了一下设计方案: 下面直接上代码了: 日志阅读器: 1 package com.fjn.tools.log.reader; 2 3 import java.io.File; 4 import java.util.LinkedList; 5 import java.util.List; 6 import java.util.Scan

对下载到RSS阅读器里订阅内容

网络推广方法有很多,RSS推广就是其中的一种,RSS订阅能够为网站增加访问量,这是众人皆知的事实.不过,如何推广RSS,让更多人知道并促使更多人订阅RSS,却是一个很大的问题.下面就有我给大家讲解一下什么事RSS推广,如何利用RSS进行网络推广. 首先来说说什么是RSS? RSS是在线共享内容的一种简单方式(也叫聚合内容,Really Simple Syndication).通常在时效性比较强的内容上使用RSS订阅能更快速获取信息.网站提供RSS输出,有利于让用户获取网站内容的最新信息.网络用户

(android高仿系列)今日头条 --新闻阅读器 (三) 完结 、总结 篇

从写第一篇今日头条高仿系列开始,到现在已经过去了1个多月了,其实大体都做好了,就是迟迟没有放出来,因为我觉得,做这个东西也是有个过程的,我想把这个模仿中一步一步学习的过程,按照自己的思路写下来,在根据碰到的知识点和问题,并且罗列出这些东西的知识点和使用方法.如果你单纯的把做好的一个DEMO拿去改改用用,那样,你永远不知道里面用到的内容是涉及到什么知识点,用什么方法实现,那样就没有多少提升价值而言了. 近期都是在通过开发文档把以前的一些东西重新过一遍,看好多网友都催促想要新版本的,那我就在这里先把

SAX实现的简易RSS阅读器

RSS RSS是简易信息聚合,用户可以订阅多个RSS源,从而在不打开网站页面的情况下阅读RSS输出的网站内容. 一个RSS文件就是一段规范的XML数据,如:http://sse.tongji.edu.cn/SSEMainRSS.aspx SAX与DOM SAX(Simple API for XML)是一个事件驱动的顺序访问XML解析API.不同于DOM(Document Object Model)将整个XML文档作为一个整体,SAX解析器按顺序解析XML文档的每个部分. DOM解析器在任何处理开

《Yii2 By Example》第2章:创建一个简单的新闻阅读器

第2章 创建一个简单的新闻阅读器 本章内容包含:创建第一个控制器,用于展示新闻条目列表和详情:学习控制器和视图之间的交互:自定义视图的布局. 本章结构如下: 创建控制器和动作 创建用于展示新闻列表的视图 控制器是如何将数据传送到视图的 例子--创建一个控制器,展示静态新闻条目列表和详情 将常用视图内容分割成多个可复用视图 例子--在视图中进行部分渲染 创建静态页面 在视图和布局之前共享数据 例子--根据URL参数更换布局背景 使用动态模块布局 例子--添加展示广告信息的动态盒 使用多个布局 例子

五款PC端小说阅读器 readbook、非常酷阅读器、iSilo、AlReader、haalireader

        本文主要推荐的是功能强大界面简单电脑(windows系统)单机使用的小说阅读器~以阅读TXT之流的主流类小说文件,只想要会联网会更新可以发评论发微博的朋友可以节省点时间,按ctrl+w吧~觉得想要单机软件的朋友请继续往下看~          这篇博文居然还在有人点击和回复,有点出乎我的意料,当初写这篇文章的本意是因为发现想搜一个简单实用的单机阅读器实在是困难重重,搜索结果总是被各大广告阅读器干扰,千辛万苦终于找到之后觉得应该分享一下以飨同好:虽然时间过去了蛮久,但从回复的朋友来