android自定义组件(手机加速球+水面波动效果)(精选6篇)由网友“荆乔”投稿提供,以下文章小编为您整理的android自定义组件(手机加速球+水面波动效果),供大家阅读。
篇1:android自定义组件(手机加速球+水面波动效果)
实现代码
首先画出波浪线,通过通过贝塞尔曲线
for (int i = 0; i < 20; i++) {path.rQuadTo(20, size, 40, 0);path.rQuadTo(20, -size, 40, 0); }
然后让曲线动起来
private Handler handler = new Handler { @Override public void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) { case 0x23: count += 5; if (count >= 80) {count = 0; } if (isAdd) {size++;if (size >10) { isAdd = false;} } else {size--;if (size <= -10) { isAdd = true;} } invalidate(); sendEmptyMessageDelayed(0x23, 100); break;
篇2:android自定义组件(手机加速球+水面波动效果)
/** * Created by Administrator on /9/17. */public class MyPathView extends View { private Path path; private Paint paintRect; private Paint paintBubble; private Paint paintWave; private int width; private int height; private int count = 0; private int size = 0; private int courentProgress=325; private boolean isAdd = true; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) { case 0x23: count += 5; if (count >= 80) {count = 0; } if (isAdd) {size++;if (size >10) { isAdd = false;} } else {size--;if (size <= -10) { isAdd = true;} } invalidate(); sendEmptyMessageDelayed(0x23, 100); break; case 0x11: if(courentProgress<550){courentProgress+=5;sendEmptyMessageDelayed(0x11,50);invalidate(); } break;} } }; public MyPathView(Context context, AttributeSet attrs) { super(context, attrs); paintWave = new Paint(); paintWave.setStyle(Paint.Style.STROKE); paintWave.setTextSize(70); paintRect = new Paint(); paintRect.setStrokeWidth(5); paintRect.setColor(Color.rgb(251,122,108)); PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP); paintRect.setStyle(Paint.Style.FILL); paintRect.setXfermode(mode); paintBubble = new Paint(); paintBubble.setStyle(Paint.Style.FILL); paintBubble.setColor(Color.rgb(86,111,141)); path = new Path(); handler.sendEmptyMessageDelayed(0x23, 1000); } private Bitmap bitmapBubble; private Canvas canvasBubble; protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec); height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); setMeasuredDimension(width, height); bitmapBubble = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); canvasBubble = new Canvas(bitmapBubble); } private float x; private float y; @Override public boolean onTouchEvent(MotionEvent event) { x = event.getX(); y = event.getY(); switch (event.getAction()) {case MotionEvent.ACTION_DOWN: if (x>250&&x<550&&y>250&&y<550) { handler.sendEmptyMessage(0x11); return true; } } return super.onTouchEvent(event); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.rgb( 246, 235, 188)); canvasBubble.drawCircle(400, 400, 150, paintBubble); path.reset(); path.moveTo(600, courentProgress); path.lineTo(600, 600); path.lineTo(count, 600); path.lineTo(count, courentProgress); for (int i = 0; i < 20; i++) {path.rQuadTo(20, size, 40, 0);path.rQuadTo(20, -size, 40, 0); } path.close(); canvasBubble.drawPath(path, paintRect); canvas.drawBitmap(bitmapBubble, 0, 0, null); canvas.drawText((550-courentProgress)/3+%,400,400,paintWave); }}
篇3:android自定义组件(手机加速球+水面波动效果)
这一步需要用到的知识比较多
1我来给讲解一下,画布的问题;首先onDraw提供一个默认的canvas;我们可以想象一下,这块画布就是手机屏幕,我们可以使用这块画布画背景色;
2我们的球形加速球,是通过两层图重叠取得重叠的部分
示意图如下
我们先画出了矩形,代码如下
path.reset; path.moveTo(600, courentProgress); path.lineTo(600, 600); path.lineTo(count, 600); path.lineTo(count, courentProgress);
然后画出了圆形,设置画笔,使得只显示两部分重叠的部分:
此处可参考上一篇:blog.csdn.net/taoolee/article/details/48527917
PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP); paintRect.setXfermode(mode);
这样显示的效果就是
【3】实现点击加速球,加速效果
先要添加点击事件<?www.2cto.com/kf/ware/vc/“ target=”_blank“ class=”keylink“>vcD4NCjxwcmUgY2xhc3M9”brush:java;“>private float x; private float y; @Override public boolean onTouchEvent(MotionEvent event) { x = event.getX(); y = event.getY(); switch (event.getAction()) {case MotionEvent.ACTION_DOWN: if (x>250&&x<550&&y>250&&y<550) { handler.sendEmptyMessage(0x11); return true; } } return super.onTouchEvent(event); }
然后使用handler处理改变当前水面高度,
我们先默认初始高度75%
private int courentProgress=325; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) { case 0x11: if(courentProgress<550){courentProgress+=5;sendEmptyMessageDelayed(0x11,50);invalidate(); } break;} } };
篇4:Android自定义Viewgroup切换View带有吸附效果
这里我下载的网络图片,同样可以将图片放到res下设置ImageView的内容
public class DragPageViewAdapter { private static final String TAG = DragPageViewAdapter; private ListmDatas; private Context mContext; private LayoutInflater inflater; /** * 宽和高 */ int width; int height; public DragPageViewAdapter(Context mContext) { this.mContext = mContext; inflater = LayoutInflater.from(mContext); width = (int) (0.8*DragViewActivity.mScreenWidth);//宽是屏幕宽度的0.8height = (int) (0.8*DragViewActivity.mScreenWidth); } public int getCount(){ return mDatas==null?0:mDatas.size(); } public int getItemId(int position){ return position; } public Object getItem(int position){ return mDatas==null?null:mDatas.get(position); } public View getView(int position, View convertView, ViewGroup parent){ LogHelper.d(TAG, position : + position); final ImageView imageView = new ImageView(mContext); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width,height); params.addRule(Gravity.CENTER); imageView.setLayoutParams(params); imageView.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.gray_border)); ViewHelper.setAlpha(imageView,1.0f); String url = mDatas.get(position).getPictureUrl(); if (!Utils.stringIsNull(url)){url = url.substring(0, url.lastIndexOf(.)) + --300x300.png;//UILHelper.loadImageUrl(url, imageView,0);UILHelper.loadImageUrl(url, new SimpleImageLoadingListener(){ @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { imageView.setImageBitmap(loadedImage); }}); } convertView = imageView; convertView.setTag(mDatas.get(position));// viewHolder.mImageView.setImageResource((Integer) mDatas.get(position)); return convertView; } public void setData(List data){ mDatas = data; } private class ViewHolder{ ImageView mImageView; }}
通过此Adapter将所需要的图片匆网络下载下来,当我们需要的时候ImageView自己去请求下载,并将数据通过setTag的方法与ImageView进行绑定
篇5:Android自定义Viewgroup切换View带有吸附效果
直接上代码,我们要做的事情 a.onMeasure方法测量子自己及子view b.onLayout方法给子view进行布局 c.onTouchEvent处理触摸事件,up的时候判断是否切换下一个view,如果不是的话通过属性动画将view的状态恢复 d.绑定切换的回调 e.切换后把当前的View从viewgruop中remove掉,add一个需要加载的view,同时给当前view赋值为切换的view,保证viewgroup中不多于指定的子view个数,保证不OOM
public class DragPageView extends ViewGroup{ private static final String TAG = DragPageView; /** * 适配器 */ private DragPageViewAdapter mAdapter; /** * view的个数 */ private int ONE_SCREEN_COUNT = 2; /** * 屏幕的宽和高 */ private int mScrenWidth; private int mScreenHeight; /** * 子元素的宽 高 */ private int mChildWidth; private int mChildHeight; /** * 当前最后一张图片的index */ private int mLastIndex; /** * 当前第一张图片的下标 */ private int mFirstIndex; /** * 当前显示View */ private View mFirstView; /** * 之前触摸的x y */ private int mDownX; private int mDownY; /** * 当前触摸的x y */ private int mCurX; private int mCurY; public static int mDirection = -1; public static final int DIRECTION_LEFT_TO_RIGHT = 1; public static final int DIRECTION_RIGHT_TO_LEFT = 2; /** * 保存View与位置的键值对 */ private MapmViewMap = new HashMap; /** * 最大旋转角度 */ private int ROTATE_DEGREE = 30; private int CHILD_OFFSET = 10; /** * 保存回调接口 */ private OnImageSavedListener mOnImageSavedListener; public void setOnImageSavedListener(OnImageSavedListener mOnImageSavedListener) { this.mOnImageSavedListener = mOnImageSavedListener; } public DragPageView(Context context) { this(context, null); } public DragPageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public DragPageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //获得屏幕宽和高 WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics metrics = new DisplayMetrics(); windowManager.getDefaultDisplay().getMetrics(metrics); mScrenWidth = metrics.widthPixels; mScreenHeight = metrics.heightPixels; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { /** * 获得此ViewGroup上级容器为其推荐的宽和高,以及计算模式 */ int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); // 计算出所有的childView的宽和高 measureChildren(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(mScrenWidth, sizeHeight); } @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);mChildWidth = child.getMeasuredWidth();mChildHeight = child.getMeasuredHeight();int left = getWidth()/2-mChildWidth/2;int top = getHeight()/2- mChildHeight*2/3;int right = left + mChildWidth;int bottom = top + mChildHeight;if (i == 0) child.layout(left+CHILD_OFFSET, top+CHILD_OFFSET, right+CHILD_OFFSET, bottom+CHILD_OFFSET);else child.layout(left, top, right, bottom); } } public void initDatas(DragPageViewAdapter mAdapter){ this.mAdapter = mAdapter; initView(); } @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void initView() { removeAllViews(); for (int i = 0; i < ONE_SCREEN_COUNT; i++){View view = mAdapter.getView(i, null, this);mViewMap.put(i,view); } //mViewMap中存放的view倒叙添加到ViewGroup,因为ViewGroup index = 0在最底层 for (int j= ONE_SCREEN_COUNT -1; j>=0;j--){addView(mViewMap.get(j));if (j == 0){ mFirstView = mViewMap.get(j);} } mLastIndex = ONE_SCREEN_COUNT -1; mFirstIndex = mLastIndex - ONE_SCREEN_COUNT-1; } @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override public boolean onTouchEvent(MotionEvent event) { int focusX = (int) event.getX(); int focusY = (int) event.getY(); switch (event.getAction()){case MotionEvent.ACTION_DOWN: mDownX = mCurX = focusX; mDownY = mCurY = focusY; break;case MotionEvent.ACTION_MOVE: final int deltaX = focusX - mCurX; final int deltaY = focusY-mCurY ; if (Math.abs(deltaX) >5 || Math.abs(deltaY)>5){ if (focusX >mDownX){mDirection = DIRECTION_LEFT_TO_RIGHT; }else {mDirection = DIRECTION_RIGHT_TO_LEFT; } handlerScroll(deltaX, deltaY);// mFirstView.setPivotX((float) (mFirstView.getMeasuredWidth()*0.5));// mFirstView.setPivotY(mFirstView.getMeasuredHeight()); mFirstView.setRotation(ROTATE_DEGREE*(focusX-mDownX)/mChildWidth); } mCurX = focusX; mCurY = focusY; break;case MotionEvent.ACTION_UP: LogHelper.d(TAG, mPreX : + mDownX + mPreY + mDownY + mCurX : + mCurX + mCurY : + mCurY); if (Math.abs(mCurX- mDownX)>mChildWidth/2 && mLastIndex < mAdapter.getCount()){ loadNextImage(); }else { resetView(); } break; } return true; } private void resetView() { PropertyValuesHolder aX= PropertyValuesHolder.ofFloat(translationX, 0); PropertyValuesHolder aY = PropertyValuesHolder.ofFloat(translationY,0); PropertyValuesHolder rotate = PropertyValuesHolder.ofFloat(rotation,0); ObjectAnimator.ofPropertyValuesHolder(mFirstView, oaX, oaY, rotate).start(); } public void loadNextImage() { ObjectAnimator aX = null; ObjectAnimator aRotate = null; if (mLastIndex == mAdapter.getCount()) return; if (mDirection == DIRECTION_LEFT_TO_RIGHT){aX = new ObjectAnimator().ofFloat(mFirstView, translationX,800);aRotate = new ObjectAnimator().ofFloat(mFirstView, rotation,ROTATE_DEGREE);//通知回调已保存的viewif (mOnImageSavedListener != null){ mOnImageSavedListener.onImageSaved(mFirstView);} }else {aX = new ObjectAnimator().ofFloat(mFirstView, translationX, -800);aRotate = new ObjectAnimator().ofFloat(mFirstView, rotation, -ROTATE_DEGREE);if (mOnImageSavedListener != null){ mOnImageSavedListener.onImageDelete(mFirstView);} } oaX.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) { //动画结束后load下一张图片 mViewMap.remove(mFirstIndex); //删除view removeAllViews(); //获取下一张图片 if ((mLastIndex+1)>= mAdapter.getCount()){ addView(mViewMap.get(mLastIndex)); }else { View view = mAdapter.getView(++mLastIndex, null, DragPageView.this); mViewMap.put(mLastIndex, view); addView(mViewMap.get(mLastIndex)); addView(mViewMap.get(mLastIndex-1)); mFirstView = mViewMap.get(mLastIndex-1); }} }); //开启动画 oaRotate.start(); oaX.start(); } @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void handlerScroll(float distanceX, float distanceY) { int newLeft = (int) (mFirstView.getLeft()+distanceX); int newTop = (int) (mFirstView.getTop()+distanceY); float[] deltaVector = {distanceX, distanceY}; mFirstView.getMatrix().mapVectors(deltaVector); mFirstView.setTranslationX(mFirstView.getTranslationX() + deltaVector[0]); mFirstView.setTranslationY(mFirstView.getTranslationY() + deltaVector[1]); } public interface OnImageSavedListener{ public void onImageSaved(View view); public void onImageDelete(View view); }}
篇6:Android自定义Viewgroup切换View带有吸附效果
负责的事情 a.请求数据初始化Adapter及ViewGroup b.切换回调的响应 c.点击按键切换的事件处理
public class DragViewActivity extends BaseActivity{ private static final String TAG = DragViewActivity; private DragPageViewAdapter adapter; private DragPageView mDragView; private int pageIndex = 1; private int pageSize = 21; private int total; /** * userId */ private String userId; //网路请求的数据 private Listlists; //保存的view的信息 private ListmSavedView; private WxCollocationRandomList mViewInfo; /** * 屏幕宽和高 */ public static int mScreenWidth; public static int mScreenHeight; private TextView mSkip; private TextView mSave; private TextView mDone; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dragview_act); WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); DisplayMetrics displayMetrics = new DisplayMetrics(); windowManager.getDefaultDisplay().getMetrics(displayMetrics); mScreenWidth = displayMetrics.widthPixels; mScreenHeight = displayMetrics.heightPixels; userId = SettingsManager.getSettingsManager(this).getUserId(); initView(); httpGetImageInfo(pageIndex); } private void httpGetImageInfo(final int pageIndex) { JSONObject bject = new JSONObject(); try {object.put(pageIndex, pageIndex);object.put(pageSize, pageSize); } catch (JSONException e) {e.printStackTrace(); } if (pageIndex == 1) {showProgress(getResources().getString(R.string.app_data_loading)); } HttpsRequestUtil.doHttpsVolleyPost(this, SOAServices.COLLOCATION_SERVICE, SOAMethods.RANDOM_COLLOCATION, HttpsRequestUtil.GET, object, new Response.Listener(){ @Override public void onResponse(String response) {if (pageIndex ==1){ closeProgress();}transformData(response); } }, new Response.ErrorListener(){ @Override public void onErrorResponse(VolleyError error) {closeProgress(); } }); } /** * 请求的数据,进行初始化adapter及Viewgroup的初始化 * @param response */ private void transformData(String response) { Gson gson = new Gson(); WxCollocationRandomFilter wxCollocationRandomFilter= gson.fromJson(response, WxCollocationRandomFilter.class); total = wxCollocationRandomFilter.getTotal(); if (total == 0)return; lists = wxCollocationRandomFilter.getCollocationRandomLists(); adapter.setData(lists); mDragView.initDatas(adapter); } private void initView() { mDragView = (DragPageView) findViewById(R.id.dragView); adapter = new DragPageViewAdapter(this); mDragView.setOnImageSavedListener(new DragPageView.OnImageSavedListener() {@Overridepublic void onImageSaved(View view) { mViewInfo = (WxCollocationRandomList) view.getTag(); httpSaveFavorite(mViewInfo);}@Overridepublic void onImageDelete(View view) { mViewInfo = (WxCollocationRandomList) view.getTag(); httpDeleteFavorite(mViewInfo);} }); mSkip = (TextView) findViewById(R.id.skip); mSave = (TextView) findViewById(R.id.save); mDone = (TextView) findViewById(R.id.done); mSkip.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) { mDragView.mDirection = mDragView.DIRECTION_RIGHT_TO_LEFT; mDragView.loadNextImage();} }); mSave.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) { mDragView.mDirection = mDragView.DIRECTION_LEFT_TO_RIGHT; mDragView.loadNextImage();} }); mDone.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) { DragViewActivity.this.finish();} }); } /** * 喜欢 * @param mViewInfo 搭配信息 sourcE_TYPE 1 商品 2 搭配 */ private void httpSaveFavorite(WxCollocationRandomList mViewInfo) { JSONObject jsonObject = new JSONObject(); try {jsonObject.put(sourcE_ID, mViewInfo.getId());jsonObject.put(userId,userId);jsonObject.put(creatE_USER, mViewInfo.getCreateUser());jsonObject.put(sourcE_TYPE, 2); } catch (JSONException e) {e.printStackTrace(); } HttpsRequestUtil.doHttpsVolleyPost(DragViewActivity.this, SOAServices.ORDER_SERVICE, SOAMethods.FAVORITE_ADD, HttpsRequestUtil.POST, jsonObject, new Response.Listener() { @Override public void onResponse(String response) {LogHelper.d(TAG, SaveFavorite Success!); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) {LogHelper.d(TAG, SaveFavorite Error!); } }); } /** * 删除喜欢 * @param mViewInfo 搭配信息 sourcE_TYPE 1 商品 2 搭配 */ private void httpDeleteFavorite(WxCollocationRandomList mViewInfo) { JSONObject jsonObject = new JSONObject(); try {jsonObject.put(sourcE_ID, mViewInfo.getId());jsonObject.put(userId,userId);jsonObject.put(creatE_USER, mViewInfo.getCreateUser());jsonObject.put(sourcE_TYPE, 2); } catch (JSONException e) {e.printStackTrace(); } HttpsRequestUtil.doHttpsVolleyPost(DragViewActivity.this, SOAServices.ORDER_SERVICE, SOAMethods.FAVORITE_DELETE, HttpsRequestUtil.POST, jsonObject, new Response.Listener() { @Override public void onResponse(String response) {LogHelper.d(TAG, DeleteFavorite Success!); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) {LogHelper.d(TAG, DeleteFavorite Error!); } }); }}
★ android学习十九(WebView的用法)
★ 安卓项目总结
★ 安卓论文开题报告
★ Alcon 3: 另一个开源的ActionScript调试工具网页设计
★ 工程师实习报告
★ 电子信息工程专业的实习报告
★ 百度面试Android面试题
★ 笔试题目2
★ 计算机专业毕业论文开题报告
★ 安卓实习心得感悟
《android自定义组件(手机加速球+水面波动效果).doc》
将本文的Word文档下载到电脑,方便收藏和打印
【android自定义组件(手机加速球+水面波动效果)(精选6篇)】相关文章:
安卓开发心得实例2023-05-17
从零开始学Android应用安全测试(Part1)2022-04-30
关于信息工程专业的开题报告2023-01-11
浅谈细水雾灭火系统在地铁中的应用论文2022-10-01
工业热电阻自动检定系统的软件设计与开发论文2022-09-08
安卓的英文是什么2023-11-13
java的实习报告2023-07-31
对tmpfs的性能测试2022-07-21
面试自我介绍宝典2023-12-15
面试题及答案2023-04-15