在android中实现类似uc和墨迹天气的左右拖动效果

在android中实现类似uc和墨迹天气的左右拖动效果,第1张

概述复制代码代码如下:importandroid.app.Activity;importandroid.os.Bundle;importandroid.content.Context;importandroid.graphics.Color;importandroid.util.Log;importandroid.view.Gravity;importandroid.view.Moti 复制代码 代码如下:
import androID.app.Activity;
import androID.os.Bundle;
import androID.content.Context;
import androID.graphics.color;
import androID.util.Log;
import androID.vIEw.Gravity;
import androID.vIEw.MotionEvent;
import androID.vIEw.VIEw;
import androID.vIEw.VIEwGroup;
import androID.vIEw.VIEw.OnClickListener;
import androID.Widget.ArrayAdapter;
import androID.Widget.button;
import androID.Widget.CheckBox;
import androID.Widget.EditText;
import androID.Widget.linearLayout;
import androID.Widget.tableLayout;
import androID.Widget.TextVIEw;
public class FlinggalleryActivity extends Activity
{
private final int color_red = color.argb(100,200,0);
private final int color_green = color.argb(100,0);
private final int color_blue = color.argb(100,200);
private final int color_yellow = color.argb(100,0);
private final int color_purple = color.argb(100,200);
private final String[] mLabelArray = {"VIEw1","VIEw2","VIEw3","VIEw4","VIEw5"};
private final int[] mcolorArray = {color_red,color_green,color_blue,color_yellow,color_purple};
private Flinggallery mgallery;
private CheckBox mCheckBox;
// Note: The following handler is critical to correct function of
// the Flinggallery class. This enables the Flinggallery class to
// detect when the motion event has ended by finger being lifted
@OverrIDe
public boolean ontouchEvent(MotionEvent event)
{
return mgallery.ongallerytouchEvent(event);
}
public voID onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mgallery = new Flinggallery(this);
mgallery.setpaddingWIDth(5);
mgallery.setAdapter(new ArrayAdapter<String>(getApplicationContext(),androID.R.layout.simple_List_item_1,mLabelArray)
{
@OverrIDe
public VIEw getVIEw(int position,VIEw convertVIEw,VIEwGroup parent)
{
Log.d("111","count="+position);
// if (convertVIEw != null && convertVIEw instanceof galleryVIEwItem)
// {
// galleryVIEwItem galleryVIEw = (galleryVIEwItem) convertVIEw;
//
// galleryVIEw.mEdit1.setText("");
// galleryVIEw.mText1.setText(mLabelArray[position]);
// galleryVIEw.mText1.setBackgroundcolor(mcolorArray[position]);
// galleryVIEw.mText2.setText(mLabelArray[position]);
// galleryVIEw.mText2.setBackgroundcolor(mcolorArray[position]);
//
// Log.d("111","count="+position);
//
// return galleryVIEw;
//
// }

return new galleryVIEwItem(getApplicationContext(),position);
}
});
linearLayout layout = new linearLayout(getApplicationContext());
layout.setorIEntation(linearLayout.VERTICAL);
linearLayout.LayoutParams layoutParams = new linearLayout.LayoutParams(
linearLayout.LayoutParams.MATCH_PARENT,
linearLayout.LayoutParams.MATCH_PARENT);
layoutParams.setmargins(10,10,10);
layoutParams.weight = 1.0f;
layout.addVIEw(mgallery,layoutParams);

mCheckBox = new CheckBox(getApplicationContext());
mCheckBox.setText("gallery is Circular");
mCheckBox.setText("gallery is Circular");
mCheckBox.setpadding(50,10);
mCheckBox.setTextSize(30);
mCheckBox.setChecked(true);
mCheckBox.setonClickListener(new OnClickListener()
{
@OverrIDe
public voID onClick(VIEw vIEw)
{
mgallery.setIsgalleryCircular(mCheckBox.isChecked());
}
});
layout.addVIEw(mCheckBox,new linearLayout.LayoutParams(
linearLayout.LayoutParams.MATCH_PARENT,
linearLayout.LayoutParams.WRAP_CONTENT));

setContentVIEw(layout);
}
private class galleryVIEwItem extends tableLayout
{
private EditText mEdit1;
private TextVIEw mText1;
private TextVIEw mText2;
private button mbutton1;
private button mbutton2;
public galleryVIEwItem(Context context,int position)
{
super(context);
this.setorIEntation(linearLayout.VERTICAL);
this.setLayoutParams(new linearLayout.LayoutParams(
linearLayout.LayoutParams.MATCH_PARENT,
linearLayout.LayoutParams.MATCH_PARENT));

mEdit1 = new EditText(context);
this.addVIEw(mEdit1,
linearLayout.LayoutParams.WRAP_CONTENT));
mText1 = new TextVIEw(context);
mText1.setText(mLabelArray[position]);
mText1.setTextSize(30);
mText1.setGravity(Gravity.left);
mText1.setBackgroundcolor(mcolorArray[position]);
this.addVIEw(mText1,
linearLayout.LayoutParams.WRAP_CONTENT));
mbutton1 = new button(context);
mbutton1.setText("<<");
mbutton1.setGravity(Gravity.left);
mbutton1.setonClickListener(new OnClickListener()
{
@OverrIDe
public voID onClick(VIEw vIEw)
{
mgallery.movePrevIoUs();
}
});
this.addVIEw(mbutton1,
linearLayout.LayoutParams.WRAP_CONTENT));
mbutton2 = new button(context);
mbutton2.setText(">>");
mbutton2.setGravity(Gravity.RIGHT);
mbutton2.setonClickListener(new OnClickListener()
{
@OverrIDe
public voID onClick(VIEw vIEw)
{
mgallery.moveNext();
}
});
this.addVIEw(mbutton2,
linearLayout.LayoutParams.WRAP_CONTENT));
mText2 = new TextVIEw(context);
mText2.setText(mLabelArray[position]);
mText2.setTextSize(30);
mText2.setGravity(Gravity.RIGHT);
mText2.setBackgroundcolor(mcolorArray[position]);
this.addVIEw(mText2,
linearLayout.LayoutParams.MATCH_PARENT,1));
}
}
}

[代码]Flinggallery
复制代码 代码如下:
import androID.content.Context;
import androID.vIEw.GestureDetector;
import androID.vIEw.KeyEvent;
import androID.vIEw.MotionEvent;
import androID.vIEw.VIEw;
import androID.vIEw.animation.Animation;
import androID.vIEw.animation.AnimationUtils;
import androID.vIEw.animation.Interpolator;
import androID.vIEw.animation.transformation;
import androID.Widget.Adapter;
import androID.Widget.FrameLayout;
import androID.Widget.linearLayout;
// Todo:
// 1. In order to improve performance Cache screen bitmap and use for animation
// 2. Establish superfluous memory allocations and delay or replace with reused objects
// Probably need to make sure we are not allocating objects (strings,etc.) in loops
public class Flinggallery extends FrameLayout
{
// Constants

private final int swipe_min_distance = 120;
private final int swipe_max_off_path = 250;
private final int swipe_threshold_veloicty = 400;
// PropertIEs
private int mVIEwpaddingWIDth = 0;
private int mAnimationDuration = 250;
private float mSnapborderRatio = 0.5f;
private boolean mIsgalleryCircular = true;
// Members
private int mgalleryWIDth = 0;
private boolean mIstouched = false;
private boolean mIsDragging = false;
private float mCurrentOffset = 0.0f;
private long mScrollTimestamp = 0;
private int mFlingDirection = 0;
private int mCurrentposition = 0;
private int mCurrentVIEwNumber = 0;
private Context mContext;
private Adapter mAdapter;
private FlinggalleryVIEw[] mVIEws;
private FlinggalleryAnimation mAnimation;
private GestureDetector mGestureDetector;
private Interpolator mDecelerateInterpolater;
public Flinggallery(Context context)
{
super(context);
mContext = context;
mAdapter = null;

mVIEws = new FlinggalleryVIEw[3];
mVIEws[0] = new FlinggalleryVIEw(0,this);
mVIEws[1] = new FlinggalleryVIEw(1,this);
mVIEws[2] = new FlinggalleryVIEw(2,this);
mAnimation = new FlinggalleryAnimation();
mGestureDetector = new GestureDetector(new FlingGestureDetector());
mDecelerateInterpolater = AnimationUtils.loadInterpolator(mContext,androID.R.anim.decelerate_interpolator);
}
public voID setpaddingWIDth(int vIEwpaddingWIDth)
{
mVIEwpaddingWIDth = vIEwpaddingWIDth;
}
public voID setAnimationDuration(int animationDuration)
{
mAnimationDuration = animationDuration;
}

public voID setSnapborderRatio(float snapborderRatio)
{
mSnapborderRatio = snapborderRatio;
}
public voID setIsgalleryCircular(boolean isgalleryCircular)
{
if (mIsgalleryCircular != isgalleryCircular)
{
mIsgalleryCircular = isgalleryCircular;

if (mCurrentposition == getFirstposition())
{
// We need to reload the vIEw immediately to the left to change it to circular vIEw or blank
mVIEws[getPrevVIEwNumber(mCurrentVIEwNumber)].recycleVIEw(getPrevposition(mCurrentposition));
}

if (mCurrentposition == getLastposition())
{
// We need to reload the vIEw immediately to the right to change it to circular vIEw or blank
mVIEws[getNextVIEwNumber(mCurrentVIEwNumber)].recycleVIEw(getNextposition(mCurrentposition));
}
}
}
public int getgalleryCount()
{
return (mAdapter == null) ? 0 : mAdapter.getCount();
}
public int getFirstposition()
{
return 0;
}
public int getLastposition()
{
return (getgalleryCount() == 0) ? 0 : getgalleryCount() - 1;
}
private int getPrevposition(int relativeposition)
{
int prevposition = relativeposition - 1;
if (prevposition < getFirstposition())
{
prevposition = getFirstposition() - 1;
if (mIsgalleryCircular == true)
{
prevposition = getLastposition();
}
}
return prevposition;
}
private int getNextposition(int relativeposition)
{
int nextposition = relativeposition + 1;
if (nextposition > getLastposition())
{
nextposition = getLastposition() + 1;
if (mIsgalleryCircular == true)
{
nextposition = getFirstposition();
}
}
return nextposition;
}
private int getPrevVIEwNumber(int relativeVIEwNumber)
{
return (relativeVIEwNumber == 0) ? 2 : relativeVIEwNumber - 1;
}
private int getNextVIEwNumber(int relativeVIEwNumber)
{
return (relativeVIEwNumber == 2) ? 0 : relativeVIEwNumber + 1;
}

@OverrIDe
protected voID onLayout(boolean changed,int left,int top,int right,int bottom)
{
super.onLayout(changed,left,top,right,bottom);
// Calculate our vIEw wIDth
mgalleryWIDth = right - left;
if (changed == true)
{
// position vIEws at correct starting offsets
mVIEws[0].setoffset(0,mCurrentVIEwNumber);
mVIEws[1].setoffset(0,mCurrentVIEwNumber);
mVIEws[2].setoffset(0,mCurrentVIEwNumber);
}
}
public voID setAdapter(Adapter adapter)
{
mAdapter = adapter;
mCurrentposition = 0;
mCurrentVIEwNumber = 0;
// Load the initial vIEws from adapter
mVIEws[0].recycleVIEw(mCurrentposition);
mVIEws[1].recycleVIEw(getNextposition(mCurrentposition));
mVIEws[2].recycleVIEw(getPrevposition(mCurrentposition));
// position vIEws at correct starting offsets
mVIEws[0].setoffset(0,mCurrentVIEwNumber);
}
private int getVIEwOffset(int vIEwNumber,int relativeVIEwNumber)
{
// Determine wIDth including configured padding wIDth
int offsetWIDth = mgalleryWIDth + mVIEwpaddingWIDth;
// position the prevIoUs vIEw one measured wIDth to left
if (vIEwNumber == getPrevVIEwNumber(relativeVIEwNumber))
{
return offsetWIDth;
}
// position the next vIEw one measured wIDth to the right
if (vIEwNumber == getNextVIEwNumber(relativeVIEwNumber))
{
return offsetWIDth * -1;
}
return 0;
}
voID movePrevIoUs()
{
// SlIDe to prevIoUs vIEw
mFlingDirection = 1;
processGesture();
}
voID moveNext()
{
// SlIDe to next vIEw
mFlingDirection = -1;
processGesture();
}
@OverrIDe
public boolean onKeyDown(int keyCode,KeyEvent event)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_left:
movePrevIoUs();
return true;

case KeyEvent.KEYCODE_DPAD_RIGHT:
moveNext();
return true;

case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
}
return super.onKeyDown(keyCode,event);
}
public boolean ongallerytouchEvent(MotionEvent event)
{
boolean consumed = mGestureDetector.ontouchEvent(event);

if (event.getAction() == MotionEvent.ACTION_UP)
{
if (mIstouched || mIsDragging)
{
processScrollSnap();
processGesture();
}
}

return consumed;
}
voID processGesture()
{
int newVIEwNumber = mCurrentVIEwNumber;
int reloadVIEwNumber = 0;
int reloadposition = 0;
mIstouched = false;
mIsDragging = false;
if (mFlingDirection > 0)
{
if (mCurrentposition > getFirstposition() || mIsgalleryCircular == true)
{
// Determine prevIoUs vIEw and outgoing vIEw to recycle
newVIEwNumber = getPrevVIEwNumber(mCurrentVIEwNumber);
mCurrentposition = getPrevposition(mCurrentposition);
reloadVIEwNumber = getNextVIEwNumber(mCurrentVIEwNumber);
reloadposition = getPrevposition(mCurrentposition);
}
}
if (mFlingDirection < 0)
{
if (mCurrentposition < getLastposition() || mIsgalleryCircular == true)
{
// Determine the next vIEw and outgoing vIEw to recycle
newVIEwNumber = getNextVIEwNumber(mCurrentVIEwNumber);
mCurrentposition = getNextposition(mCurrentposition);
reloadVIEwNumber = getPrevVIEwNumber(mCurrentVIEwNumber);
reloadposition = getNextposition(mCurrentposition);
}
}
if (newVIEwNumber != mCurrentVIEwNumber)
{
mCurrentVIEwNumber = newVIEwNumber;
// Reload outgoing vIEw from adapter in new position
mVIEws[reloadVIEwNumber].recycleVIEw(reloadposition);
}
// Ensure input focus on the current vIEw
mVIEws[mCurrentVIEwNumber].requestFocus();
// Run the slIDe animations for vIEw Transitions
mAnimation.prepareAnimation(mCurrentVIEwNumber);
this.startAnimation(mAnimation);
// reset fling state
mFlingDirection = 0;
}
voID processScrollSnap()
{
// Snap to next vIEw if scrolled passed snap position
float rollEdgeWIDth = mgalleryWIDth * mSnapborderRatio;
int rollOffset = mgalleryWIDth - (int) rollEdgeWIDth;
int currentOffset = mVIEws[mCurrentVIEwNumber].getCurrentOffset();
if (currentOffset <= rollOffset * -1)
{
// Snap to prevIoUs vIEw
mFlingDirection = 1;
}
if (currentOffset >= rollOffset)
{
// Snap to next vIEw
mFlingDirection = -1;
}
}
private class FlinggalleryVIEw
{
private int mVIEwNumber;
private FrameLayout mParentLayout;

private FrameLayout mInvalIDLayout = null;
private linearLayout mInternalLayout = null;
private VIEw mExternalVIEw = null;
public FlinggalleryVIEw(int vIEwNumber,FrameLayout parentLayout)
{
mVIEwNumber = vIEwNumber;
mParentLayout = parentLayout;
// InvalID layout is used when outsIDe gallery
mInvalIDLayout = new FrameLayout(mContext);
mInvalIDLayout.setLayoutParams(new linearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
// Internal layout is permanent for duration
mInternalLayout = new linearLayout(mContext);
mInternalLayout.setLayoutParams(new linearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
mParentLayout.addVIEw(mInternalLayout);
}
public voID recycleVIEw(int newposition)
{
if (mExternalVIEw != null)
{
mInternalLayout.removeVIEw(mExternalVIEw);
}
if (mAdapter != null)
{
if (newposition >= getFirstposition() && newposition <= getLastposition())
{
mExternalVIEw = mAdapter.getVIEw(newposition,mExternalVIEw,mInternalLayout);
}
else
{
mExternalVIEw = mInvalIDLayout;
}
}
if (mExternalVIEw != null)
{
mInternalLayout.addVIEw(mExternalVIEw,new linearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
}
}
public voID setoffset(int xOffset,int yOffset,int relativeVIEwNumber)
{
// Scroll the target vIEw relative to its own position relative to currently displayed vIEw
mInternalLayout.scrollTo(getVIEwOffset(mVIEwNumber,relativeVIEwNumber) + xOffset,yOffset);
}

public int getCurrentOffset()
{
// Return the current scroll position
return mInternalLayout.getScrollX();
}
public voID requestFocus()
{
mInternalLayout.requestFocus();
}
}
private class FlinggalleryAnimation extends Animation
{
private boolean mIsAnimationInProgres;
private int mrelativeVIEwNumber;
private int mInitialOffset;
private int mTargetoffset;
private int mTargetdistance;
public FlinggalleryAnimation()
{
mIsAnimationInProgres = false;
mrelativeVIEwNumber = 0;
mInitialOffset = 0;
mTargetoffset = 0;
mTargetdistance = 0;
}
public voID prepareAnimation(int relativeVIEwNumber)
{
// If we are animating relative to a new vIEw
if (mrelativeVIEwNumber != relativeVIEwNumber)
{
if (mIsAnimationInProgres == true)
{
// We only have three vIEws so if requested again to animate in same direction we must snap
int newDirection = (relativeVIEwNumber == getPrevVIEwNumber(mrelativeVIEwNumber)) ? 1 : -1;
int animDirection = (mTargetdistance < 0) ? 1 : -1;
// If animation in same direction
if (animDirection == newDirection)
{
// Ran out of time to animate so snap to the target offset
mVIEws[0].setoffset(mTargetoffset,mrelativeVIEwNumber);
mVIEws[1].setoffset(mTargetoffset,mrelativeVIEwNumber);
mVIEws[2].setoffset(mTargetoffset,mrelativeVIEwNumber);
}
}

// Set relative vIEw number for animation
mrelativeVIEwNumber = relativeVIEwNumber;
}
// Note: In this implementation the targetoffset will always be zero
// as we are centering the vIEw; but we include the calculations of
// targetoffset and targetdistance for use in future implementations
mInitialOffset = mVIEws[mrelativeVIEwNumber].getCurrentOffset();
mTargetoffset = getVIEwOffset(mrelativeVIEwNumber,mrelativeVIEwNumber);
mTargetdistance = mTargetoffset - mInitialOffset;
// Configure base animation propertIEs
this.setDuration(mAnimationDuration);
this.setInterpolator(mDecelerateInterpolater);
// Start/continued animation
mIsAnimationInProgres = true;
}
@OverrIDe
protected voID applytransformation(float interpolatedTime,transformation transformation)
{
// Ensure interpolatedTime does not over-shoot then calculate new offset
interpolatedTime = (interpolatedTime > 1.0f) ? 1.0f : interpolatedTime;
int offset = mInitialOffset + (int) (mTargetdistance * interpolatedTime);
for (int vIEwNumber = 0; vIEwNumber < 3; vIEwNumber++)
{
// Only need to animate the visible vIEws as the other vIEw will always be off-screen
if ((mTargetdistance > 0 && vIEwNumber != getNextVIEwNumber(mrelativeVIEwNumber)) ||
(mTargetdistance < 0 && vIEwNumber != getPrevVIEwNumber(mrelativeVIEwNumber)))
{
mVIEws[vIEwNumber].setoffset(offset,mrelativeVIEwNumber);
}
}
}
@OverrIDe
public boolean gettransformation(long currentTime,transformation outtransformation)
{
if (super.gettransformation(currentTime,outtransformation) == false)
{
// Perform final adjustment to offsets to cleanup animation
mVIEws[0].setoffset(mTargetoffset,mrelativeVIEwNumber);
// Reached the animation target
mIsAnimationInProgres = false;
return false;
}
// Cancel if the screen touched
if (mIstouched || mIsDragging)
{
// Note that at this point we still consIDer ourselves to be animating
// because we have not yet reached the target offset; its just that the
// user has temporarily interrupted the animation with a touch gesture
return false;
}
return true;
}
}
private class FlingGestureDetector extends GestureDetector.SimpleOnGestureListener
{
@OverrIDe
public boolean onDown(MotionEvent e)
{
// Stop animation
mIstouched = true;
// reset fling state
mFlingDirection = 0;
return true;
}
@OverrIDe
public boolean onScroll(MotionEvent e1,MotionEvent e2,float distanceX,float distanceY)
{
if (e2.getAction() == MotionEvent.ACTION_MOVE)
{
if (mIsDragging == false)
{
// Stop animation
mIstouched = true;

// Reconfigure scroll
mIsDragging = true;
mFlingDirection = 0;
mScrollTimestamp = System.currentTimeMillis();
mCurrentOffset = mVIEws[mCurrentVIEwNumber].getCurrentOffset();
}
float maxVeLocity = mgalleryWIDth / (mAnimationDuration / 1000.0f);
long timestampDelta = System.currentTimeMillis() - mScrollTimestamp;
float maxScrollDelta = maxVeLocity * (timestampDelta / 1000.0f);
float currentScrollDelta = e1.getX() - e2.getX();
if (currentScrollDelta < maxScrollDelta * -1) currentScrollDelta = maxScrollDelta * -1;
if (currentScrollDelta > maxScrollDelta) currentScrollDelta = maxScrollDelta;
int scrollOffset = Math.round(mCurrentOffset + currentScrollDelta);
// We can't scroll more than the wIDth of our own frame layout
if (scrollOffset >= mgalleryWIDth) scrollOffset = mgalleryWIDth;
if (scrollOffset <= mgalleryWIDth * -1) scrollOffset = mgalleryWIDth * -1;

mVIEws[0].setoffset(scrollOffset,mCurrentVIEwNumber);
mVIEws[1].setoffset(scrollOffset,mCurrentVIEwNumber);
mVIEws[2].setoffset(scrollOffset,mCurrentVIEwNumber);
}
return false;
}
@OverrIDe
public boolean onFling(MotionEvent e1,float veLocityX,float veLocityY)
{
if (Math.abs(e1.getY() - e2.getY()) <= swipe_max_off_path)
{
if (e2.getX() - e1.getX() > swipe_min_distance && Math.abs(veLocityX) > swipe_threshold_veloicty)
{
movePrevIoUs();
}
if(e1.getX() - e2.getX() > swipe_min_distance && Math.abs(veLocityX) > swipe_threshold_veloicty)
{
moveNext();
}
}
return false;
}
@OverrIDe
public voID onLongPress(MotionEvent e)
{
// Finalise scrolling
mFlingDirection = 0;
processGesture();
}
@OverrIDe
public voID onShowPress(MotionEvent e)
{
}
@OverrIDe
public boolean onSingleTapUp(MotionEvent e)
{
// reset fling state
mFlingDirection = 0;
return false;
}
}
}
您可能感兴趣的文章:android 添加随意拖动的桌面悬浮窗口Android 仿淘宝、京东商品详情页向上拖动查看图文详情控件DEMO详解Android 可拖动的seekbar自定义进度值Android编程之控件可拖动的实现方法Android编程实现图标拖动效果的方法Android实现ImageView图片缩放和拖动Android自定义View实现拖动选择按钮Android编程实现图片的浏览、缩放、拖动和自动居中效果Android实现跟随手指拖动并自动贴边的View样式(实例demo)Android使用ViewPager实现类似laucher左右拖动效果 总结

以上是内存溢出为你收集整理的在android中实现类似uc和墨迹天气的左右拖动效果全部内容,希望文章能够帮你解决在android中实现类似uc和墨迹天气的左右拖动效果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1142772.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存