`
iaiai
  • 浏览: 2204634 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android 很炫的拖动效果(源码)

 
阅读更多
先来看效果图:



就两个文件,新建一个项目把下面两个文件放进去,设置好启动activity就行了

FlingGallery.java
package com.iaiai.fg;

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 
/**
 * 
 * <p>
 * Title: FlingGallery.java
 * </p>
 * <p>
 * E-Mail: 176291935@qq.com
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2012-7-7 上午10:18:53
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */
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;
	}

    @Override  
    public boolean onTouchEvent(MotionEvent event){  
        return onGalleryTouchEvent(event);  
    }

	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, 0, mCurrentViewNumber);
			mViews[1].setOffset(0, 0, mCurrentViewNumber);
			mViews[2].setOffset(0, 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, 0, mCurrentViewNumber);
		mViews[1].setOffset(0, 0, mCurrentViewNumber);
		mViews[2].setOffset(0, 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, 0,
								mRelativeViewNumber);
						mViews[1].setOffset(mTargetOffset, 0,
								mRelativeViewNumber);
						mViews[2].setOffset(mTargetOffset, 0,
								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, 0, 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, 0, mRelativeViewNumber);
				mViews[1].setOffset(mTargetOffset, 0, mRelativeViewNumber);
				mViews[2].setOffset(mTargetOffset, 0, 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, 0, mCurrentViewNumber);
				mViews[1].setOffset(scrollOffset, 0, mCurrentViewNumber);
				mViews[2].setOffset(scrollOffset, 0, mCurrentViewNumber);
			}

			return false;
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, 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;
		}
	}
}


MainActivity.java
package com.iaiai.fg;

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;

/**
 * 
 * <p>
 * Title: MainActivity.java
 * </p>
 * <p>
 * E-Mail: 176291935@qq.com
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2012-7-7 上午10:18:53
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */
public class MainActivity extends Activity {
	private final int color_red = Color.argb(100, 200, 0, 0);
	private final int color_green = Color.argb(100, 0, 200, 0);
	private final int color_blue = Color.argb(100, 0, 0, 200);
	private final int color_yellow = Color.argb(100, 200, 200, 0);
	private final int color_purple = Color.argb(100, 200, 0, 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, 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, 0, 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, new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.MATCH_PARENT,
					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, new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.MATCH_PARENT,
					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, new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.MATCH_PARENT,
					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, new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.MATCH_PARENT,
					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, new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.MATCH_PARENT,
					LinearLayout.LayoutParams.MATCH_PARENT, 1));
		}
	}

}
  • 大小: 27.3 KB
  • 大小: 29.2 KB
分享到:
评论

相关推荐

    Android 炫丽书架源码

    【Android 炫丽书架源码】是一个专为Android平台设计的图书展示应用的核心代码,它通过精美的视觉效果和交互设计,为用户呈现一个类似真实书架的虚拟阅读空间。这一源码实现了动态书本排列、翻页动画、书籍预览等...

    Android GridView图片拖拽效果 源码

    DraggableView GridView项目拖拽效果, 自顶一个SampleGridContainer 集成FrameLayout实现 DragController.IDragViewGroup ,里面主要提供了onDragStart ,onDragEnd,onMoveEvent 等几个方法实现拖拽效果

    Android listview 拖拽实现源码

    本篇文章将深入探讨如何在Android ListView中实现拖拽功能,并基于提供的"Android listview 拖拽实现源码"进行解析。 首先,要实现ListView的拖拽功能,我们需要自定义一个适配器(Adapter),这个适配器需要继承自...

    Android应用源码-系统工具类设计安卓源代码(82例).zip

    Android 仿UC,墨迹天气左右拖动多屏幕显示效果源码 Android 仿百度地图气泡程序源码 Android 关机和重启(reboot and shutdown)源码 Android 具有伸缩效果的ListView源码 Android 半透明Menu效果源码

    Android涂鸦马赛克效果源码!

    这个源码示例对于开发者来说具有很高的学习价值,它结合了图像处理、手势识别和自定义视图等Android开发的关键技术。通过研究和理解这些代码,开发者可以提升自己在Android图像处理领域的技能,同时也能为自己的应用...

    Android开发之google源码——图片拖拽效果的实现

    本文将基于提供的“Android开发之google源码——图片拖拽效果的实现”资源,深入探讨如何在Android平台上创建这样的功能。 首先,我们要理解图片拖拽效果的核心原理。这种效果通常依赖于触摸事件(MotionEvent)的...

    安卓Android源码——拖动按钮效果源码.zip

    这个压缩包“安卓Android源码——拖动按钮效果源码.zip”包含了实现这一功能的相关资源,包括图像文件和源代码说明。我们将深入探讨如何在Android应用中创建这种效果。 首先,源码说明.txt文件可能提供了实现拖动...

    Android源码——拖动按钮效果源码.zip

    这个"Android源码——拖动按钮效果源码.zip"文件包含了一个实现这种效果的示例代码,我们可以从中学到如何在Android应用中创建可拖动的按钮。以下是对这个源码的详细解析: 1. **拖动事件处理**: Android系统通过...

    android抽屉效果源码

    总的来说,这个“android抽屉效果源码”是一个很好的学习资源,它涵盖了Android手势检测、视图动画、自定义布局等多个关键知识点。通过分析和运行这个示例,开发者可以深入理解Android滑动抽屉的实现原理,并将其...

    Android 拖动按钮效果源码.rar

    本项目提供的"Android 拖动按钮效果源码"是一个实现此类功能的示例代码,可以帮助开发者了解如何在自己的应用中实现类似的效果。 首先,我们要明白拖动按钮的核心机制。这种效果通常基于触摸事件(MotionEvent)...

    Android 拖动按钮效果源码

    下面我们将深入探讨如何实现这样的功能,以及在这个"Android拖动按钮效果源码"中可能包含的关键知识点。 首先,我们需要理解Android中的触摸事件处理机制。在Android中,触摸事件通过MotionEvent类进行传递。当用户...

    Android代码-炫丽书架源码.zip

    【Android代码-炫丽书架源码.zip】这个压缩包文件是针对Android平台的一个开发资源,主要用于实现一种视觉效果出色的“书架”界面。在Android应用开发中,这样的设计通常用于电子书应用或者图书类应用,模拟真实书架...

    Android 拖动按钮效果源码.zip

    【Android 拖动按钮效果源码】是一个用于Android应用开发的资源,它提供了一种独特的用户交互方式,即拖动按钮。这个源码实现了一个可滑动的按钮,用户可以通过手势滑动来触发不同的操作,增加了应用的交互性和趣味...

    Android 拖动按钮效果源码.zip源码资源下载

    本资源提供的是一个实现Android拖动按钮效果的源码示例,可以帮助开发者更好地理解和实现这种功能。 在Android应用中,通常我们使用的按钮是静态的,用户只需点击即可触发相应的操作。然而,拖动按钮增加了用户的...

    Android源码——炫丽书架源码.zip

    这个"Android源码——炫丽书架源码.zip"文件包含了一个实现这种效果的示例代码,可以帮助开发者理解和学习如何在自己的应用中实现类似的动态书架效果。 书架效果的核心在于模拟真实世界中的书本排列和翻页动画。在...

    Android拖动按钮效果源码.zip

    这个"Android拖动按钮效果源码.zip"包含了实现这一功能的源代码,对于开发者来说,是一个很好的学习和参考资源。下面将详细解析这一技术及其相关知识点。 首先,我们要理解Android中的触摸事件处理机制。在Android...

    Android 拖动按钮效果源码.zip项目安卓应用源码下载

    Android 拖动按钮效果源码.zip项目安卓应用源码下载Android 拖动按钮效果源码.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考

    安卓Android源码——拖动Button显示效果.zip

    本项目"安卓Android源码——拖动Button显示效果.zip"聚焦于如何通过编程技术让Button控件在用户的手势操作下产生独特的视觉反馈。在深入探讨这个主题之前,我们需要了解Android开发的基本知识,包括Activity、布局...

Global site tag (gtag.js) - Google Analytics