Android 實現自定義圓形listview功能的實例代碼
最近遇到一個需求需要圓形listview作為懸浮窗,費了九牛二虎之力終于開發出來了,特別有成就感,下面分享下案例,項目原因,只能分享一部分供大家參考1.有圖有真相

下面就來講解下代碼:1.自定義listview
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;public class CircleListView extends ViewGroup { private static final double intervalAngel = 60;//子view之間的間隔角 int circleR;//圓的半徑 int ccx;//圓心的x軸坐標 int ccy;//圓心的y軸坐標 double angel = 0;//偏移角度 private float oldTouchY;//上一次觸摸的y軸位置 private boolean isScrolling = false;//是否在滑動狀態 private Bitmap circleBitmap = null; private Rect src; private Rect dst; private Paint paint; private Adapter adapter = new Adapter(this) { @Override public View getView(int position) { return new View(getContext()); } }; public CircleListView(Context context) { super(context); setWillNotDraw(false); paint = new Paint(); } public CircleListView(Context context, AttributeSet attrs) { super(context, attrs); setWillNotDraw(false); paint = new Paint();// TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleListView);// setCircleBitMap(ta.getResourceId(R.styleable.CircleListView_circleDrawable, 0));// ta.recycle(); } private void setCircleBitMap(int drawableId) { if (drawableId != 0) { circleBitmap = BitmapFactory.decodeResource(getResources(), drawableId); } else { circleBitmap = null; } } public void setAdapter(Adapter adapter) { this.adapter = adapter; refreshList(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { measureChildren(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (circleBitmap != null) { if (src == null) {src = new Rect(); } src.left = 0; src.top = 0; src.right = circleBitmap.getWidth(); src.bottom = circleBitmap.getHeight(); if (dst == null) {dst = new Rect(); } dst.left = ccx - circleBitmap.getWidth()/4; dst.top = ccy - circleBitmap.getHeight()/4; dst.right = ccx + circleBitmap.getWidth()/4; dst.bottom = ccy + circleBitmap.getHeight()/4; canvas.drawBitmap(circleBitmap, src, dst, paint); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { circleR = (getRight() - getLeft()) / 10 * 5; ccy = (int) (getHeight() * 0.5); ccx = getWidth() / 2; for (int i = 0; i < adapter.getCount(); i++) { View childView = getChildAt(i); double childViewAngel = i * intervalAngel + angel; int x = ccx + (int) (Math.sin(Math.toRadians(childViewAngel)) * circleR*0.6); int y = ccy - (int) (Math.cos(Math.toRadians(childViewAngel)) * circleR*0.6); int vl = x - childView.getMeasuredWidth() / 2; int vt = y - childView.getMeasuredHeight() / 2; int vr = x + childView.getMeasuredWidth() / 2; int vb = y + childView.getMeasuredHeight() / 2; childView.layout(vl, vt, vr, vb ); } }// @Override// public boolean dispatchTouchEvent(MotionEvent ev) {// switch (ev.getAction()) {// case MotionEvent.ACTION_DOWN://oldTouchY = ev.getY();//super.dispatchTouchEvent(ev);//return true;// case MotionEvent.ACTION_MOVE://if (!isScrolling && Math.abs(oldTouchY - ev.getY()) > 50) {// isScrolling = true;// float offSetY = 0;// oldTouchY = ev.getY();// angel += offSetY / 20;// requestLayout();// return true;//} else if (isScrolling) {// float offSetY = ev.getY() - oldTouchY;// oldTouchY = ev.getY();// if ((angel + offSetY / 20) < ((adapter.getCount() - 1) * -intervalAngel)) {// angel = (adapter.getCount() - 1) * -intervalAngel;// } else if ((angel + offSetY / 20) > 0) {// angel = 0;// } else {// angel += offSetY / 20;// }// requestLayout();// return true;//}//return super.dispatchTouchEvent(ev);// case MotionEvent.ACTION_UP://boolean notDispatch = isScrolling;//isScrolling = false;//if (notDispatch) {// return false;//} else {// performClick();// return super.dispatchTouchEvent(ev);//}// default://isScrolling = false;//return super.dispatchTouchEvent(ev);// }// } protected void refreshList() { removeAllViews(); for (int i = 0; i < adapter.getCount(); i++) { if (i == 0 && angel < -intervalAngel * (adapter.getCount() - 1)) {angel = -intervalAngel * (adapter.getCount() - 1); } addView(adapter.getView(i)); if (adapter.getCount() == 1) {setPosition(0); } } invalidate(); } protected void setPosition(int position) { angel = -position * intervalAngel; }}
2.實體類
import android.graphics.drawable.Drawable;public class Files { private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getApp_name() { return app_name; } public void setApp_name(String app_name) { this.app_name = app_name; } public String getPackagename() { return packagename; } public void setPackagename(String packagename) { this.packagename = packagename; } public int getImg_bg_id() { return img_bg_id; } public void setImg_bg_id(int img_bg_id) { this.img_bg_id = img_bg_id; } public boolean isShow() { return isShow; } public void setShow(boolean show) { isShow = show; } private Drawable imgDrawable; public Drawable getImgDrawable() { return imgDrawable; } public void setImgDrawable(Drawable imgDrawable) { this.imgDrawable = imgDrawable; } private boolean isShow; private String app_name; private String packagename; private int img_bg_id;}
3.適配器
import android.view.View;import java.util.ArrayList;public abstract class Adapter { private CircleListView circleListView; private ArrayList<Files> allAppList; public Adapter(CircleListView circleListView) { this.circleListView = circleListView; } public int getCount() { return allAppList.size(); } public abstract View getView(int position); public void notifyDataChanged() { circleListView.refreshList(); } public void setPosition(int position) { if (position > getCount() - 1) { position = getCount() - 1; } else if (position < 0) { position = 0; } circleListView.setPosition(position); }}
4.float.xml 引用:
<?xml version='1.0' encoding='utf-8'?><RelativeLayout xmlns:android='http://schemas.android.com/apk/res/android' android:layout_width='match_parent' android:layout_height='match_parent'> <ImageView android: android:layout_width='79px' android:layout_height='79px' android:scaleType='fitCenter' android:layout_centerInParent='true' android:background='@drawable/main_selector_floatbtn' android:clickable='true' /> <RelativeLayout android: android:layout_width='300px' android:layout_height='300px' android:layout_centerInParent='true' android:background='@drawable/float_display_bg' android:visibility='gone'> <com.xinrui.headsettest.circlelistview.CircleListView android: android:layout_width='300px' android:layout_height='300px' android:layout_centerHorizontal='true'/> <ImageView android: android:layout_width='70px' android:layout_height='70px' android:scaleType='fitCenter' android:layout_centerInParent='true' android:background='@drawable/float_main_icon' android:clickable='true'/> </RelativeLayout></RelativeLayout>
5.Activity中應用:
import android.app.Activity;import android.os.Bundle;import android.provider.ContactsContract;import android.view.LayoutInflater;import android.view.View;import android.widget.ImageView;import android.widget.RelativeLayout;import android.widget.TextView;import android.widget.Toast;import com.xinrui.headsettest.circlelistview.Adapter;import com.xinrui.headsettest.circlelistview.CircleListView;import com.xinrui.headsettest.circlelistview.Files;import java.util.ArrayList;public class FloatActivity extends Activity implements View.OnClickListener{ private ImageView floatImg, float_main_img; private RelativeLayout float_area; private CircleListView circle_list_view; private Adapter adapter; private ArrayList<Files> appDataList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.float_layout); getData(); init(); } private void getData(){ appDataList=new ArrayList<>(); Files files = new Files(); files.setApp_name(this.getResources().getString(R.string.calculator_txt)); files.setImg_bg_id(R.drawable.main_selector_calculator); appDataList.add(files); Files files0 = new Files(); files0.setApp_name(this.getResources().getString(R.string.calendar_txt)); files0.setImg_bg_id(R.drawable.main_selector_calendar); appDataList.add(files0); Files files1 = new Files(); files1.setApp_name(this.getResources().getString(R.string.timer_txt)); files1.setImg_bg_id(R.drawable.main_selector_clock); appDataList.add(files1); Files files2 = new Files(); files2.setApp_name(this.getResources().getString(R.string.vip_txt)); files2.setImg_bg_id(R.drawable.main_selector_vip); appDataList.add(files2); Files files3 = new Files(); files3.setApp_name(this.getResources().getString(R.string.screen_shots_txt)); files3.setImg_bg_id(R.drawable.main_selector_screenshot); appDataList.add(files3); Files files4 = new Files(); files4.setApp_name(this.getResources().getString(R.string.recording_screen_txt)); files4.setImg_bg_id(R.drawable.main_selector_recordingscreen); appDataList.add(files4); } private void init() { float_area = (RelativeLayout) findViewById(R.id.float_area); floatImg = (ImageView) findViewById(R.id.float_btn); float_main_img = (ImageView) findViewById(R.id.float_main_img); float_main_img.bringToFront(); floatImg.setOnClickListener(this); float_main_img.setOnClickListener(this); circle_list_view = findViewById(R.id.circle_list_view); adapter = new Adapter(circle_list_view) { @Override public View getView(final int position) {View view = LayoutInflater.from(FloatActivity.this).inflate(R.layout.item_app,null);TextView app_name = view.findViewById(R.id.app_name);ImageView app_img = view.findViewById(R.id.app_img);ImageView delete_img = view.findViewById(R.id.delete_icon);delete_img.bringToFront();final Files files = appDataList.get(position);app_name.setText(files.getApp_name());app_img.setImageResource(files.getImg_bg_id());if(files.isShow()){ delete_img.setVisibility(View.VISIBLE);}else{ delete_img.setVisibility(View.INVISIBLE);}delete_img.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { appDataList.remove(position); Files file = new Files(); file.setShow(false); file.setImg_bg_id(R.drawable.main_selector_additem); file.setApp_name(FloatActivity.this.getResources().getString(R.string.custom_txt)); appDataList.add(position,file); adapter.notifyDataChanged(); }});view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(FloatActivity.this,'my is '+files.getApp_name(),Toast.LENGTH_SHORT).show(); }});view.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if(!files.getApp_name().equals(FloatActivity.this.getResources().getString(R.string.custom_txt))) { for (Files file : appDataList) {if (file.getApp_name().equals(files.getApp_name())) { file.setShow(true);} else { file.setShow(false);} } adapter.notifyDataChanged(); } return true; }});return view; } @Override public int getCount() {return appDataList.size(); } }; circle_list_view.setAdapter(adapter); adapter.setPosition(0); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.float_main_img:float_area.setVisibility(View.GONE);floatImg.setVisibility(View.VISIBLE);break; case R.id.float_btn:float_area.setVisibility(View.VISIBLE);floatImg.setVisibility(View.GONE);break; } }}
大功告成就這樣實現了圓形listview…
到此這篇關于Android 實現自定義圓形listview功能的實例代碼的文章就介紹到這了,更多相關android 自定義圓形listview內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!
相關文章:
1. 使用Python webdriver圖書館搶座自動預約的正確方法2. SpringBoot整合Redis的步驟3. ASP.NET MVC使用jQuery ui的progressbar實現進度條4. Python3 json模塊之編碼解碼方法講解5. 在線php代碼縮進、代碼美化工具:PHP Formatter6. android H5本地緩存加載優化的實戰7. PHP如何開啟Opcache功能提升程序處理效率8. PHP程序員簡單的開展服務治理架構操作詳解(二)9. 詳解如何使用Net將HTML簡歷導出為PDF格式10.排行榜使用Python webdriver圖書館搶座自動預約的正確方法 1. android H5本地緩存加載優化的實戰 2. ASP.NET MVC使用jQuery ui的progressbar實現進度條 3. 詳解如何使用Net將HTML簡歷導出為PDF格式 4. 5. PHP程序員簡單的開展服務治理架構操作詳解(二) 6. PHP如何開啟Opcache功能提升程序處理效率 7. SpringBoot整合Redis的步驟 8. Python3 json模塊之編碼解碼方法講解 9. IntelliJ IDEA設置自動提示功能快捷鍵的方法 10. 在線php代碼縮進、代碼美化工具:PHP Formatter

網公網安備