知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X(jué)表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷(xiāo)的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷(xiāo)工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
Android開(kāi)發(fā)之自定義View專(zhuān)題(三):自定義GridView
發(fā)表時(shí)間:2020-10-19
發(fā)布人:葵宇科技
瀏覽次數(shù):67
gridview作為android開(kāi)辟中常用的組件,其功能十分強(qiáng)大年夜。然則,我們有時(shí)刻有很獨(dú)特別的需求,須要在其基本長(zhǎng)進(jìn)行改革。有時(shí)刻會(huì)有移動(dòng)gridView中item地位的需求,這個(gè)網(wǎng)上已經(jīng)有很多例子,博主就不在描述。今天博主講的是移動(dòng)gridView中item中的內(nèi)容。博主沒(méi)看過(guò)網(wǎng)上那些移動(dòng)item地位的demo,不知道其道理是不是和博主想的一樣。博主思慮過(guò),似乎博主的┞封種實(shí)現(xiàn)道理似乎也可以用作實(shí)現(xiàn)移動(dòng)item地位。而之前博主百思不得其解的小米手機(jī)的桌面的自定義亂序排放,似乎也可以用這個(gè)道理去實(shí)現(xiàn)。好了,廢話不多說(shuō),先上效不雅圖
[img]http://img.blog.csdn.net/20150104221936104?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmljdG9yZnJlZWRvbQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
[img]http://img.blog.csdn.net/20150104222013000?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmljdG9yZnJlZWRvbQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center[img]http://img.blog.csdn.net/20150104222001704?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmljdG9yZnJlZWRvbQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center[img]http://img.blog.csdn.net/20150104222024328?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmljdG9yZnJlZWRvbQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center[img]http://img.blog.csdn.net/20150104222028953?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmljdG9yZnJlZWRvbQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center[img]http://img.blog.csdn.net/20150104222018022?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmljdG9yZnJlZWRvbQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center[img]http://img.blog.csdn.net/20150104222041875?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmljdG9yZnJlZWRvbQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center[img]http://img.blog.csdn.net/20150104222047531?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmljdG9yZnJlZWRvbQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
這里博主就以數(shù)字為內(nèi)容來(lái)演示,不合的數(shù)字item的背景色彩不合來(lái)區(qū)分,長(zhǎng)按住一個(gè)item后可以移動(dòng),每次移動(dòng),移動(dòng)的item減1,移動(dòng)到的item加1。效不雅還可以吧。好了,上代碼,大年夜家一路進(jìn)修。懂得其實(shí)現(xiàn)道理的同窗完全可以本身修改代碼開(kāi)辟可移動(dòng)item的gridView
完全項(xiàng)面前目今載地址:http://download.csdn.net/detail/victorfreedom/8326829
(比來(lái)收集不給力,github上傳有問(wèn)題,等明天最后一篇自定義view專(zhuān)題講解完了,再將所有項(xiàng)目一路上傳吧,不介懷那點(diǎn)分的同窗可以先下載)
package com.freedom.gridview; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.PixelFormat; import android.util.AttributeSet; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.WindowManager; import android.view.animation.AnimationUtils; import android.widget.AdapterView; import android.widget.GridView; import android.widget.ImageView; import android.widget.Toast; import com.freedom.gridview.adapter.GridViewAdapter; import com.freedom.gridview.bean.Data; /** * @ClassName: FreedomGridView * @author victor_freedom ([email protected]) * @createddate 2015-1-4 下晝10:25:52 * @Description: 可移動(dòng)item內(nèi)容的gridView */ @SuppressLint("NewApi") public class FreedomGridView extends GridView { // 是否在移動(dòng)中 private boolean isMove = false; // 是否是第一次移動(dòng) private boolean isFirst = true; // 是否是長(zhǎng)按 private boolean isLongClick = false; // 圖形 private Bitmap bitmap; // 移動(dòng)的視圖 private ImageView moveView = null; // 偏移量 private int offsetX, offsetY; // 在屏幕中觸摸的地位 private int touchPositionInScreen; // 移動(dòng)的目標(biāo)地位 private int moveToPosition; // 在ITEM中觸摸的坐標(biāo) private int touchPositionInItemX, touchPositionInItemY; // 移動(dòng)速度 private int scaledTouchSlop; // 移動(dòng)過(guò)程中,高低邊距剖斷主動(dòng)滑動(dòng)距離 private int upScrollBounce; private int downScrollBounce; // 窗體治理者,用于添加視圖 private WindowManager windowManager = null; private WindowManager.LayoutParams layoutParams = null; private GridViewAdapter adapter; public FreedomGridView(Context context) { super(context); scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } public FreedomGridView(Context context, AttributeSet attrs) { super(context, attrs); } public FreedomGridView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * 長(zhǎng)按剖斷 */ private Runnable longPressRun = new Runnable() { @Override public void run() { isLongClick = true; } }; /** * @Title: contains * @Description: 斷定是否觸摸坐標(biāo)是否在視圖瑯綾擎 * @param v * @param xInView * @param yInView * @return * @throws */ private boolean contains(View v, int xInView, int yInView) { if (v instanceof ImageView) { return ((ImageView) v).getDrawable().getBounds() .contains(xInView, yInView); } return v.getBackground().getBounds().contains(xInView, yInView); } @Override public boolean onTouchEvent(MotionEvent ev) { // 拿到適配器 if (null == adapter || adapter.isEmpty()) { adapter = (GridViewAdapter) getAdapter(); } switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: // 拿到相對(duì)于觸摸視圖的坐標(biāo) int x = (int) ev.getX(); int y = (int) ev.getY(); // 拿到觸摸地位 touchPositionInScreen = moveToPosition = this.pointToPosition(x, y); // 斷定地位是否有效 if (moveToPosition == AdapterView.INVALID_POSITION) { break; } // 拿到當(dāng)前觸摸的可見(jiàn)item ViewGroup itemView = (ViewGroup) this.getChildAt(moveToPosition - this.getFirstVisiblePosition()); // 拿到點(diǎn)擊地位相對(duì)于ITEM視圖的偏移量 touchPositionInItemY = y - itemView.getTop(); touchPositionInItemX = x - itemView.getLeft(); // 拿到item視圖瑯綾擎的控件 View view = itemView.findViewById(R.id.desk_back); // 斷定點(diǎn)擊地位是否在視圖瑯綾擎 if (this.contains(view, touchPositionInItemX, touchPositionInItemX)) { try { int[] locationInScreen = new int[2]; view.getLocationOnScreen(locationInScreen); } catch (NullPointerException e) { break; } } // 移動(dòng)視圖時(shí)刻的偏移量 this.offsetX = (int) (ev.getRawX() - x); this.offsetY = (int) (ev.getRawY() - y); // 獲取觸發(fā)當(dāng)拖動(dòng)視圖到最頂端或者最底端主動(dòng)滾動(dòng)視圖的邊距 upScrollBounce = Math.min(y - scaledTouchSlop, getHeight() / 3); downScrollBounce = Math.max(y + scaledTouchSlop, getHeight() * 2 / 3); itemView.setDrawingCacheEnabled(true); // 拿item視圖的bitmap bitmap = Bitmap.createBitmap(itemView.getDrawingCache()); itemView.destroyDrawingCache(); postDelayed(longPressRun, 1000); break; case MotionEvent.ACTION_MOVE: if (isLongClick) { int mx = (int) ev.getX(); int my = (int) ev.getY(); // 第一次移動(dòng),創(chuàng)建移動(dòng)視圖 if (isFirst) initWindowManager(bitmap, mx, my); onMove(mx, my); // 移除之前的runable removeCallbacks(longPressRun); return true; } break; case MotionEvent.ACTION_UP: int upY = (int) ev.getY(); int upX = (int) ev.getX(); if (isMove && isLongClick) { stopMove(); completeMove(upX, upY); isMove = false; isLongClick = false; break; } removeCallbacks(longPressRun); } return super.onTouchEvent(ev); } /** * @Title: initWindowManager * @Description: 創(chuàng)建移動(dòng)視圖 * @param bm * @param x * @param y * @throws */ public void initWindowManager(Bitmap bm, int x, int y) { stopMove(); isFirst = false; layoutParams = new WindowManager.LayoutParams(); layoutParams.gravity = Gravity.TOP | Gravity.LEFT; layoutParams.horizontalMargin = layoutParams.verticalMargin = 0; layoutParams.x = x - touchPositionInItemX + offsetX; layoutParams.y = y - touchPositionInItemY + offsetY; layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; layoutParams.format = PixelFormat.TRANSLUCENT; layoutParams.windowAnimations = 0; windowManager = (WindowManager) this.getContext().getSystemService( "window"); ImageView moveViewTemp = new ImageView(getContext()); moveViewTemp.setImageBitmap(bm); windowManager = (WindowManager) this.getContext().getSystemService( "window"); windowManager.addView(moveViewTemp, layoutParams); moveView = moveViewTemp; } /** * @Title: stopMove * @Description: 停止移動(dòng) * @throws */ public void stopMove() { if (moveView != null) { windowManager.removeView(moveView); moveView = null; } } /** * @Title: onMove * @Description: 視圖移動(dòng)的時(shí)刻觸發(fā)的辦法 * @param x * @param y * @throws */ public void onMove(int x, int y) { isMove = true; // 避免拖動(dòng)到無(wú)效區(qū)域 int tempPosition = this.pointToPosition(x, y); if (tempPosition != FreedomGridView.INVALID_POSITION) { this.moveToPosition = tempPosition; } // 移動(dòng)的時(shí)刻更新視圖地位 if (moveView != null) { layoutParams.alpha = 0.8f; layoutParams.y = y - touchPositionInItemY + offsetY; layoutParams.x = x - touchPositionInItemX + offsetX; windowManager.updateViewLayout(moveView, layoutParams); } int scrollHeight = 0; if (y < upScrollBounce) { scrollHeight = 30; } else if (y > downScrollBounce) { scrollHeight = -30; } // 觸發(fā)主動(dòng)滾動(dòng) if (scrollHeight != 0) { smoothScrollToPositionFromTop(moveToPosition, getChildAt(moveToPosition - getFirstVisiblePosition()) .getTop() + scrollHeight, 1); } } /** * @Title: completeMove * @Description: 移動(dòng)完成時(shí) * @param x * @param y * @throws */ public void completeMove(int x, int y) { isFirst = true; // 拿到停止的地位 int tempPosition = this.pointToPosition(x, y); if (tempPosition != FreedomGridView.INVALID_POSITION) { this.moveToPosition = tempPosition; } if (y < getChildAt(0).getTop()) { return; } else if (y > getChildAt(getChildCount() - 1).getBottom()) { moveToPosition = getAdapter().getCount() - 1; return; } else { // 如不雅在有效地位 if (moveToPosition >= 0 && moveToPosition < getAdapter().getCount()) { ViewGroup itemView = (ViewGroup) this.getChildAt(moveToPosition - this.getFirstVisiblePosition()); if (itemView != null) { ImageView imaveView = (ImageView) itemView .findViewById(R.id.desk_back); // 斷定是否移入了有效視圖瑯綾擎 boolean isIn = this.contains(imaveView, x - itemView.getLeft(), y - itemView.getTop()); // 如不雅已經(jīng)移入了,并且不是觸摸時(shí)的肇端地位 if (isIn) { if (moveToPosition != touchPositionInScreen) { itemView.startAnimation(AnimationUtils .loadAnimation(getContext(), R.anim.desk_scale)); Data touchData = http://www.sjsjw.com/100/000326MYM030740/((Data) adapter .getItem(touchPositionInScreen)); if (touchData.getNum() == 0) { Toast.makeText(getContext(), "數(shù)量為0弗成變更", Toast.LENGTH_SHORT).show(); return; } Data toData = (Data) adapter .getItem(moveToPosition); if (toData.getNum() == 2) { Toast.makeText(getContext(), "數(shù)量為2弗成變更", Toast.LENGTH_SHORT).show(); return; } touchData.setNum(touchData.getNum() - 1); toData.setNum(toData.getNum() + 1); adapter.notifyDataSetChanged(); } } } } } } }
相關(guān)案例查看更多
相關(guān)閱讀
- 百度排名
- 云南網(wǎng)站建設(shè)列表網(wǎng)
- 軟件定制
- 云南小程序開(kāi)發(fā)哪家好
- 企業(yè)網(wǎng)站
- asp網(wǎng)站
- 網(wǎng)絡(luò)公司聯(lián)系方式
- 網(wǎng)站建設(shè)
- 小程序生成海報(bào)
- 表單
- 快排推廣
- 跳轉(zhuǎn)小程序
- 昆明小程序代建
- 大理網(wǎng)站建設(shè)公司
- 云南網(wǎng)站建設(shè) 網(wǎng)絡(luò)服務(wù)
- 網(wǎng)站小程序
- 云南軟件定制公司
- 小程序制作
- 云南網(wǎng)站建設(shè)哪家公司好
- 云南省建設(shè)廳網(wǎng)站官網(wǎng)
- 汽車(chē)回收系統(tǒng)
- 汽車(chē)報(bào)廢管理系統(tǒng)
- uniapp開(kāi)發(fā)小程序
- 云南網(wǎng)頁(yè)制作
- 小程序開(kāi)發(fā)課程
- web開(kāi)發(fā)技術(shù)
- 網(wǎng)站開(kāi)發(fā)公司哪家好
- 汽車(chē)拆解管理軟件
- 云南網(wǎng)絡(luò)營(yíng)銷(xiāo)
- 云南軟件設(shè)計(jì)