最近比较闲,想起墨迹左右滑屏的效果该如何实现,如是在网上搜索资料,都没看到理想的效果,于是参照别人的例子自己加以修改,最终效果还行。左右滑屏是通过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
分享到:
相关推荐
在Android开发中,实现左右滑屏翻页是一种常见的交互方式,尤其在应用的主界面或者内容展示场景下,用户可以通过简单的手势切换不同的页面。本文将深入探讨如何在Android项目中实现这种滑动翻页的效果,以及如何加载...
本实例提供了一个可以直接运行的Android左右滑屏解决方案,通过查看代码和理解其工作原理,开发者可以轻松地将这种功能应用到自己的项目中。 左右滑屏通常通过ViewPager组件来实现,它是Android SDK中的一个强大...
"android左右滑屏Demo,可循环切换"这个项目旨在提供一个能够循环展示内容的滑动页面示例。下面我们将深入探讨这个话题,以及如何使用Tinker进行动态修复。 首先,Android中的滑屏效果通常是通过ViewPager组件来实现...
以上就是关于“android左右滑屏”的主要知识点,希望对你在Android开发中实现滑屏效果有所帮助。在实际项目中,还可以根据需求进行更复杂的定制,例如添加手势检测库来支持更多复杂的手势操作,或者使用第三方库如`...
[Android]左右滑屏的实现,简单易学.导入方法:file-import-general-existing projects into workspace-选择文件.如果出现Unable to resolve target 'android-6'可以去更新你的API或者也可以在project.properties下把...
Android左右滑屏滚动图片,很多APP在刚安装好初次运行,都会显示一个小圆点滑屏切换图片的效果,在QQ、微信或其它APP应用安装首次运行时,会有一个导航页特效,导航页下部显示小圆点,手机左右滑屏会切换导航页中的...
在Android开发中,实现左右滑屏的交互效果是常见的需求,比如在应用的主界面或者图片浏览器中。这种效果通常是通过使用ViewPager或者SwipeRefreshLayout等组件来实现的。下面我们将详细探讨如何在Android中实现左右...
在Android开发中,滑屏切换界面是一种常见的交互方式,它为用户提供了一种流畅且直观的浏览多页面内容的体验。这种技术广泛应用于各种应用程序,如相册、菜单系统或者滚动列表。本文将深入探讨如何在Android中实现...
ViewPager是Android SDK中的一个控件,主要用于在多个页面间进行左右滑动切换。它可以自动处理页面的滑动动画,提供流畅的用户体验。要使用ViewPager,首先在布局文件中添加ViewPager组件,然后创建一个...
在Android应用开发中,滑屏(Swipe)是用户界面中常见的交互方式,它极大地提升了用户体验。本篇文章将深入探讨如何在Android中实现滑屏功能,同时重点解析`Scroller`类的作用及其工作原理。 首先,要理解滑屏的...
以上就是实现Android左右滑屏切换的基本原理和关键步骤。通过理解并实践这些知识点,你可以创建出流畅且具有吸引力的滑屏应用。当然,实际项目中可能还需要考虑其他的细节,比如页面间的数据传递、滑动冲突的处理等...
Android 模仿微信导航页左右滑屏切换内容效果源码,类似的功能现在Android手机上很普遍 ,基本上每安装一个APP在打开时的欢迎界面,都会是连续几张的图片,用户左右滑屏,就可切换欢迎页内容,看完欢迎页,才进入到...
这是Android默认的滑屏效果,通常表现为平滑的左右滑动过渡。这种效果基于视图的缓动动画,通过设置ViewGroup的滚动属性,结合Tween Animation或者Property Animation来实现。在滑动过程中,当前页面逐渐淡出,下一...
在Android应用开发中,滑屏效果是常见的交互方式,它为用户提供流畅的界面导航体验。本文将详细讲解如何在Android中实现滑屏效果,主要涉及以下几个方面:布局设计、手势识别以及视图切换。 首先,我们需要理解...
Android实现滑屏图片左右滑动切换,可以自动滑动,仿优酷Android客户端图片左右滑动,类似电脑上的焦点图和幻灯片切换效果。编程思路:设置填充ViewPager页面的适配器,设置一个监听器,当ViewPager中的页面改变时...
在"Android ViewFlipper左右自动滑屏 源码"中,开发者通过设置定时器实现了类似广告轮播的效果,使得ViewFlipper每隔一段时间会自动向左或向右滑动到下一个子视图。 要实现这样的自动滑屏功能,我们需要做以下几步...
以上步骤基本涵盖了创建一个Android左右滑动引导界面的主要过程。通过实践和调整,你可以打造出一个既实用又吸引人的引导体验,帮助用户更好地理解和使用你的应用。在实际开发中,还可以根据需求进行更复杂的设计,...