`
不夜的星辰
  • 浏览: 88564 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

android 左右滑屏

阅读更多

最近比较闲,想起墨迹左右滑屏的效果该如何实现,如是在网上搜索资料,都没看到理想的效果,于是参照别人的例子自己加以修改,最终效果还行。左右滑屏是通过ViewGroup结合手势划屏来实现,代码如下:
ScrollLayoutTest.java
package com.scroll.test;

import com.yao_guet.test.R;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.Button;

public class ScrollLayoutTest extends Activity {
private ScrollLayout sl;
private Button btn1;
private PageControlView pageControlView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        sl = (ScrollLayout)findViewById(R.id.ScrollLayoutTest);
        pageControlView = (PageControlView) findViewById(R.id.pageControl);
        btn1 = (Button)findViewById(R.id.btn1);
        btn1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
sl.snapToScreen(1);
}
});
        sl.setOnFocusChangeListener(new OnFocusChangeListener() {

@Override
public void onFocusChange(View v, boolean hasFocus) {
int i = v.getVisibility();
Log.v("=sl.i=", i+"=");
}
});
        Log.v("=sl.getCurScreen()=", sl.getCurScreen()+"=");
        pageControlView.bindScrollLayout(sl);
    }
}
ScrollLayout.java

package com.scroll.test;

import android.content.Context;
import android.graphics.Canvas;
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;

/**
 * 仿Launcher中的WorkSapce,可以左右滑动切换屏幕的类
 *
 *
 *
 */
public class ScrollLayout extends ViewGroup {

 private static final String TAG = "ScrollLayout";
 private Scroller mScroller;
 private VelocityTracker mVelocityTracker;
 
 private int mCurScreen;
 private int mDefaultScreen = 0;
 
 private static final int TOUCH_STATE_REST = 0;
 private static final int TOUCH_STATE_SCROLLING = 1;
 
 private static final int SNAP_VELOCITY = 600;
 
 private int mTouchState = TOUCH_STATE_REST;
 private int mTouchSlop;
 private float mLastMotionX;
 private float mLastMotionY;

 public ScrollLayout(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
  // TODO Auto-generated constructor stub
 }

 public ScrollLayout(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  // TODO Auto-generated constructor stub
  mScroller = new Scroller(context);
  
  mCurScreen = mDefaultScreen;
  mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
 }

 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
  // TODO Auto-generated method stub
  if (changed) {
   int childLeft = 0;
   final int childCount = getChildCount();
   
   for (int i=0; i<childCount; i++) {
    final View childView = getChildAt(i);
    if (childView.getVisibility() != View.GONE) {
     final int childWidth = childView.getMeasuredWidth();
     childView.layout(childLeft, 0,
       childLeft+childWidth, childView.getMeasuredHeight());
     childLeft += childWidth;
    }
   }
  }
 }


    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
     Log.e(TAG, "onMeasure");
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
 
        final int width = MeasureSpec.getSize(widthMeasureSpec);  
        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);  
        if (widthMode != MeasureSpec.EXACTLY) {  
            throw new IllegalStateException("ScrollLayout only canmCurScreen run at EXACTLY mode!");
        }  
 
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);  
        if (heightMode != MeasureSpec.EXACTLY) {  
            throw new IllegalStateException("ScrollLayout only can run at EXACTLY mode!");
        }  
 
        // The children are given the same width and height as the scrollLayout  
        final int count = getChildCount();  
        for (int i = 0; i < count; i++) {  
            getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);  
        }  
        // Log.e(TAG, "moving to screen "+mCurScreen);  
        scrollTo(mCurScreen * width, 0);        
    } 
   
    /**
     * According to the position of current layout
     * scroll to the destination page.
     */
    public void snapToDestination() {
     final int screenWidth = getWidth();
     final int destScreen = (getScrollX()+ screenWidth/2)/screenWidth;
     snapToScreen(destScreen);
    }
   
    public void snapToScreen(int whichScreen) {
     // get the valid layout page
     whichScreen = Math.max(0, Math.min(whichScreen, getChildCount()-1));
     if (getScrollX() != (whichScreen*getWidth())) {
      
      final int delta = whichScreen*getWidth()-getScrollX();
      mScroller.startScroll(getScrollX(), 0,
        delta, 0, Math.abs(delta)*2);
      mCurScreen = whichScreen;
      onScreenChangeListener.onScreenChange(mCurScreen);
      invalidate();  // Redraw the layout
     }
    }
   
    public void setToScreen(int whichScreen) {
     whichScreen = Math.max(0, Math.min(whichScreen, getChildCount()-1));
     mCurScreen = whichScreen;
     scrollTo(whichScreen*getWidth(), 0);
    }
   
    public int getCurScreen() {
     return mCurScreen;
    }
   
 @Override
 public void computeScroll() {
  // TODO Auto-generated method stub
  if (mScroller.computeScrollOffset()) {
   scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
   postInvalidate();
  }
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  // TODO Auto-generated method stub
  
  if (mVelocityTracker == null) {
   mVelocityTracker = VelocityTracker.obtain();
  }
  mVelocityTracker.addMovement(event);
  
  final int action = event.getAction();
  final float x = event.getX();
  final float y = event.getY();
  
  switch (action) {
  case MotionEvent.ACTION_DOWN:
   Log.e(TAG, "event down!");
   if (!mScroller.isFinished()){
    mScroller.abortAnimation();
   }
   mLastMotionX = x;
   break;
   
  case MotionEvent.ACTION_MOVE:
   int deltaX = (int)(mLastMotionX - x);
   mLastMotionX = x;
   
            scrollBy(deltaX, 0);
   break;
   
  case MotionEvent.ACTION_UP:
   Log.e(TAG, "event : up");  
            // if (mTouchState == TOUCH_STATE_SCROLLING) {  
            final VelocityTracker velocityTracker = mVelocityTracker;  
            velocityTracker.computeCurrentVelocity(1000);  
            int velocityX = (int) velocityTracker.getXVelocity();  

            Log.e(TAG, "velocityX:"+velocityX);
           
            if (velocityX > SNAP_VELOCITY && mCurScreen > 0) {  
                // Fling enough to move left  
//             onScreenChangeListener.onScreenChange(mCurScreen - 1);
             Log.e(TAG, "snap left");
                snapToScreen(mCurScreen - 1);  
            } else if (velocityX < -SNAP_VELOCITY  
                    && mCurScreen < getChildCount() - 1) {  
                // Fling enough to move right  
             Log.e(TAG, "snap right");
//             onScreenChangeListener.onScreenChange(mCurScreen + 1);
                snapToScreen(mCurScreen + 1);  
            } else {  
                snapToDestination();  
            }  

            if (mVelocityTracker != null) {  
                mVelocityTracker.recycle();  
                mVelocityTracker = null;  
            }  
            // }  
            mTouchState = TOUCH_STATE_REST;  
   break;
  case MotionEvent.ACTION_CANCEL:
   mTouchState = TOUCH_STATE_REST;
   break;
  }
  
  return true;
 }

 @Override
 public boolean onInterceptTouchEvent(MotionEvent ev) {
  // TODO Auto-generated method stub
  Log.e(TAG, "onInterceptTouchEvent-slop:"+mTouchSlop);
  
  final int action = ev.getAction();
  if ((action == MotionEvent.ACTION_MOVE) &&
    (mTouchState != TOUCH_STATE_REST)) {
   return true;
  }
  
  final float x = ev.getX();
  final float y = ev.getY();
  
  switch (action) {
  case MotionEvent.ACTION_MOVE:
   final int xDiff = (int)Math.abs(mLastMotionX-x);
   if (xDiff>mTouchSlop) {
    mTouchState = TOUCH_STATE_SCROLLING;
    
   }
   break;
   
  case MotionEvent.ACTION_DOWN:
   mLastMotionX = x;
   mLastMotionY = y;
   mTouchState = mScroller.isFinished()? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
   break;
   
  case MotionEvent.ACTION_CANCEL:
  case MotionEvent.ACTION_UP:
   mTouchState = TOUCH_STATE_REST;
   break;
  }
  
  return mTouchState != TOUCH_STATE_REST;
 }
 
 //监听页面变动
 public interface OnScreenChangeListener{
  void onScreenChange(int currentIndex);
 }
 private OnScreenChangeListener onScreenChangeListener;

 public void setOnScreenChangeListener(
   OnScreenChangeListener onScreenChangeListener) {
  this.onScreenChangeListener = onScreenChangeListener;
 }
 
 
}
PageControlView.java

 package com.scroll.test;

import com.scroll.test.ScrollLayout.OnScreenChangeListener;
import com.yao_guet.test.R;

import android.R.integer;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class PageControlView extends LinearLayout {

 private Context context;
 private int count;
 
 public PageControlView(Context context){
  super(context);
  this.context = context;
 }
 public PageControlView(Context context, AttributeSet attrs) {
  super(context, attrs);
  this.context = context;
 }
 
 public void bindScrollLayout(ScrollLayout scrollLayout){
  this.count = scrollLayout.getChildCount();
  Log.v("=count==", count+"=");
  //初始化第一屏
  generatePageControl(0);
  scrollLayout.setOnScreenChangeListener(new OnScreenChangeListener() {
   
   @Override
   public void onScreenChange(int currentIndex) {
    
    generatePageControl(currentIndex);
   }
  });
 }
 
 private void generatePageControl(int currentIndex){
  this.removeAllViews();
  for(int i = 0;i < this.count ;i ++ ){
   Log.v("=i==", i+"=");
   ImageView imageView = new ImageView(context);
   if(i==currentIndex){
    imageView.setImageResource(R.drawable.page_indicator_focused);
   }else{
    
    imageView.setImageResource(R.drawable.page_indicator);
   }
   this.addView(imageView);
  }
 }

}
main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">
<com.scroll.test.ScrollLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/ScrollLayoutTest"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">

<LinearLayout
  android:background="#FF00"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"></LinearLayout>
 
<FrameLayout
  android:background="#F0F0"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"></FrameLayout>
 
<FrameLayout
  android:background="#F00F"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  </FrameLayout>
 
<LinearLayout
  android:background="#FF00"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <Button
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="Button1"
   android:id="@+id/btn1"/>
  </LinearLayout>


<LinearLayout
  android:layout_width="wrap_content"
  android:layout_height="wrap_content">
  <Button
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="Button2" />
  </LinearLayout>
</com.scroll.test.ScrollLayout>
 <com.scroll.test.PageControlView
    android:id="@+id/pageControl"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_alignParentBottom="true">
  </com.scroll.test.PageControlView>
</RelativeLayout>

 

如果想设置循环:

 

设置循环滑屏:
1.在ScrollLayout.java类中的snapToDestination()方法中添加:
//设置使循环(5表示总共有多少屏)
     if(destScreen == 0){
      setToScreen(5);
     }else if(destScreen == 5){
      setToScreen(0);
     }else{
        //设置不循环
         snapToScreen(destScreen);
     }

2.在setToScreen(int whichScreen)方法中添加:
//设置使循环
onScreenChangeListener.onScreenChange(mCurScreen);

 

 

http://static.apk.hiapk.com/html/2012/02/404824.html

http://static.apk.hiapk.com/html/2011/11/325301.html

http://static.apk.hiapk.com/html/2011/12/374423.html

  • 大小: 9.1 KB
  • 大小: 6.3 KB
分享到:
评论
6 楼 lauphai 2012-06-06  
全是乱码~!!!!!!!!!!!!!!!!
5 楼 596611561 2012-04-17  
你的这个循环,好像到最左边一屏再向右滑动时,会迅速向右跳过中间三屏到最右边一屏,而不是直接划到最右边一屏,没有达到循环的效果啊
4 楼 596611561 2012-04-16  
请问怎样在android默认工程里实现循环划屏呢(已经有左右划屏功能)?
3 楼 korntang 2011-12-07  
不错,学习了
2 楼 huangyu18 2011-12-02  
好像不能往里面动态的addView,只能在onCreate()里面初始化好。
1 楼 kiathee 2011-09-25  
我想问问你有没有办法让他循环呢,就是到了最后一页再过就是第一页?希望能加我qq谢谢 qq : 1057792047

相关推荐

    android 左右滑屏翻页

    在Android开发中,实现左右滑屏翻页是一种常见的交互方式,尤其在应用的主界面或者内容展示场景下,用户可以通过简单的手势切换不同的页面。本文将深入探讨如何在Android项目中实现这种滑动翻页的效果,以及如何加载...

    Android左右滑屏实例(可直接运行)

    本实例提供了一个可以直接运行的Android左右滑屏解决方案,通过查看代码和理解其工作原理,开发者可以轻松地将这种功能应用到自己的项目中。 左右滑屏通常通过ViewPager组件来实现,它是Android SDK中的一个强大...

    android左右滑屏Demo,可循环切换

    "android左右滑屏Demo,可循环切换"这个项目旨在提供一个能够循环展示内容的滑动页面示例。下面我们将深入探讨这个话题,以及如何使用Tinker进行动态修复。 首先,Android中的滑屏效果通常是通过ViewPager组件来实现...

    android左右滑屏

    以上就是关于“android左右滑屏”的主要知识点,希望对你在Android开发中实现滑屏效果有所帮助。在实际项目中,还可以根据需求进行更复杂的定制,例如添加手势检测库来支持更多复杂的手势操作,或者使用第三方库如`...

    [Android]左右滑屏的实现

    [Android]左右滑屏的实现,简单易学.导入方法:file-import-general-existing projects into workspace-选择文件.如果出现Unable to resolve target 'android-6'可以去更新你的API或者也可以在project.properties下把...

    Android 小圆点滑屏滚动切换图片效果.rar

    Android左右滑屏滚动图片,很多APP在刚安装好初次运行,都会显示一个小圆点滑屏切换图片的效果,在QQ、微信或其它APP应用安装首次运行时,会有一个导航页特效,导航页下部显示小圆点,手机左右滑屏会切换导航页中的...

    android中左右滑屏的实现

    在Android开发中,实现左右滑屏的交互效果是常见的需求,比如在应用的主界面或者图片浏览器中。这种效果通常是通过使用ViewPager或者SwipeRefreshLayout等组件来实现的。下面我们将详细探讨如何在Android中实现左右...

    滑屏切换界面

    在Android开发中,滑屏切换界面是一种常见的交互方式,它为用户提供了一种流畅且直观的浏览多页面内容的体验。这种技术广泛应用于各种应用程序,如相册、菜单系统或者滚动列表。本文将深入探讨如何在Android中实现...

    android中实现滑屏三种方法

    ViewPager是Android SDK中的一个控件,主要用于在多个页面间进行左右滑动切换。它可以自动处理页面的滑动动画,提供流畅的用户体验。要使用ViewPager,首先在布局文件中添加ViewPager组件,然后创建一个...

    Android中滑屏实现

    在Android应用开发中,滑屏(Swipe)是用户界面中常见的交互方式,它极大地提升了用户体验。本篇文章将深入探讨如何在Android中实现滑屏功能,同时重点解析`Scroller`类的作用及其工作原理。 首先,要理解滑屏的...

    左右滑屏切换

    以上就是实现Android左右滑屏切换的基本原理和关键步骤。通过理解并实践这些知识点,你可以创建出流畅且具有吸引力的滑屏应用。当然,实际项目中可能还需要考虑其他的细节,比如页面间的数据传递、滑动冲突的处理等...

    Android 模仿微信导航页左右滑屏效果源码.rar

    Android 模仿微信导航页左右滑屏切换内容效果源码,类似的功能现在Android手机上很普遍 ,基本上每安装一个APP在打开时的欢迎界面,都会是连续几张的图片,用户左右滑屏,就可切换欢迎页内容,看完欢迎页,才进入到...

    android桌面滑屏特效

    这是Android默认的滑屏效果,通常表现为平滑的左右滑动过渡。这种效果基于视图的缓动动画,通过设置ViewGroup的滚动属性,结合Tween Animation或者Property Animation来实现。在滑动过程中,当前页面逐渐淡出,下一...

    Android中滑屏效果实现

    在Android应用开发中,滑屏效果是常见的交互方式,它为用户提供流畅的界面导航体验。本文将详细讲解如何在Android中实现滑屏效果,主要涉及以下几个方面:布局设计、手势识别以及视图切换。 首先,我们需要理解...

    Android实现滑屏图片左右滑动切换.rar

    Android实现滑屏图片左右滑动切换,可以自动滑动,仿优酷Android客户端图片左右滑动,类似电脑上的焦点图和幻灯片切换效果。编程思路:设置填充ViewPager页面的适配器,设置一个监听器,当ViewPager中的页面改变时...

    Android ViewFlipper左右自动滑屏 源码

    在"Android ViewFlipper左右自动滑屏 源码"中,开发者通过设置定时器实现了类似广告轮播的效果,使得ViewFlipper每隔一段时间会自动向左或向右滑动到下一个子视图。 要实现这样的自动滑屏功能,我们需要做以下几步...

    Android实现左右滑屏(类似引导界面)

    以上步骤基本涵盖了创建一个Android左右滑动引导界面的主要过程。通过实践和调整,你可以打造出一个既实用又吸引人的引导体验,帮助用户更好地理解和使用你的应用。在实际开发中,还可以根据需求进行更复杂的设计,...

Global site tag (gtag.js) - Google Analytics