37 阅读器翻阅效果 viewGroup

来源:互联网 发布:北京奥运会圣火 知乎 编辑:程序博客网 时间:2024/05/02 02:15



---------------------------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文件里面的大小写!!!!!!!!!!!

0 1
原创粉丝点击