软件编程
位置:首页>> 软件编程>> Android编程>> Android 实现自定义圆形listview功能的实例代码

Android 实现自定义圆形listview功能的实例代码

作者:爱码士_yan  发布时间:2022-06-20 06:58:29 

标签:android,自定义圆形,listview

最近遇到一个需求需要圆形listview作为悬浮窗,费了九牛二虎之力终于开发出来了,特别有成就感,下面分享下案例,项目原因,只能分享一部分供大家参考
1.有图有真相

Android 实现自定义圆形listview功能的实例代码

下面就来讲解下代码:
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:id="@+id/float_btn"
   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:id="@+id/float_area"
   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:id="@+id/circle_list_view"
     android:layout_width="300px"
     android:layout_height="300px"
     android:layout_centerHorizontal="true"/>
   <ImageView
     android:id="@+id/float_main_img"
     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…

来源:https://blog.csdn.net/baidu_41666295/article/details/106026378

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com