android 圆形ListView实现,并附带圆角ImageView
16lz
2021-01-26
转载请注明出处:王亟亟的大牛之路
平时 垂直向下的ListView已经司空见惯,换一种带一定角度的圆角ListView应该会给用户不同的体验
项目目录:
2个自定义View一个主Activity
MainActivity
public class MainActivity extends Activity { private ListView lv; //本地图片模拟数据源 private int[] images = new int[] { R.drawable.p1, R.drawable.p2, R.drawable.p3 }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv = (ListView)findViewById(R.id.lv); lv.setAdapter(new MyAdapter(MakeData())); try { changeGroupFlag(lv); } catch (Exception e) { e.printStackTrace(); } //翻滚的过程中不断绘制 lv.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { for (int i = 0; i < lv.getChildCount(); i++) { lv.getChildAt(i).invalidate(); } } }); //监听事件,测试是否会出现item移位 lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MainActivity.this,"第"+position+"个被按到了", Toast.LENGTH_SHORT).show(); } }); } //自定义适配器 class MyAdapter extends BaseAdapter { public final class ViewHolder{ public ImageView imageView; public TextView text; } //传入的数据源 private List<String> data; public MyAdapter(List<String> data){ this.data=data; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder=new ViewHolder(); MatrixView m = (MatrixView)LayoutInflater.from(MainActivity.this).inflate(R.layout.view_list_item, null); m.setParentHeight(lv.getHeight()); convertView = m; holder.text=(TextView)convertView.findViewById(R.id.text); holder.imageView = (ImageView)convertView.findViewById(R.id.image); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); } holder.text.setText(data.get(position)+""); holder.imageView.setImageResource(images[position % images.length]); return convertView; } } public void changeGroupFlag(Object obj) throws Exception// 反射替换对所有String进行替换 { Field[] f = obj.getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredFields(); // 获得成员映射数组 for (Field tem : f) // 迭代for循环 { if (tem.getName().equals("mGroupFlags")) { tem.setAccessible(true); Integer mGroupFlags = (Integer)tem.get(obj); // 返回内容 int newGroupFlags = mGroupFlags & 0xfffff8; tem.set(obj, newGroupFlags);// 替换成员值 } } } private List<String> MakeData(){ List<String> data=new ArrayList<String>(); for(int k=0;k<100;k++){ data.add("麦麦你好 "+k); } return data; }}
自定义圆角图片
public class RoundImageView extends ImageView { private float xRadius = 10; private float yRadius = 10; private Paint paint = new Paint(); public RoundImageView(Context context) { super(context); } public RoundImageView(Context context, AttributeSet attrs) { super(context, attrs); } public float getxRadius() { return xRadius; } public void setxRadius(float xRadius) { this.xRadius = xRadius; } public float getyRadius() { return yRadius; } public void setyRadius(float yRadius) { this.yRadius = yRadius; } @SuppressWarnings("deprecation") @Override protected void onDraw(Canvas canvas) { // java.lang.ClassCastException: android.graphics.drawable.TransitionDrawable cannot be cast // to android.graphics.drawable.BitmapDrawable BitmapShader shader; if (getDrawable() instanceof BitmapDrawable) { BitmapDrawable bitmapDrawable = (BitmapDrawable)getDrawable(); // clip shader = new BitmapShader(bitmapDrawable.getBitmap(), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); RectF rect = new RectF(0.0f, 0.0f, getWidth(), getHeight()); int width = bitmapDrawable.getBitmap().getWidth(); int height = bitmapDrawable.getBitmap().getHeight(); RectF src = null; if (((float)width) / height > 1) { src = new RectF(0.0f, 0.0f, height, height); } else { src = new RectF(0.0f, 0.0f, width, width); } Matrix matrix = canvas.getMatrix(); matrix.setRectToRect(src, rect, Matrix.ScaleToFit.CENTER); shader.setLocalMatrix(matrix); // 抗锯齿 paint.setAntiAlias(true); paint.setShader(shader); // draw round circle for HeadImage or other canvas.drawRoundRect(rect, this.getWidth() / 2, this.getHeight() / 2, paint); // canvas.drawRoundRect(rect, xRadius, yRadius / 2, paint); } }}
自定义布局
public class MatrixView extends LinearLayout { private int h = 0; private float fullAngelFactor = 10f; private float fullScaleFactor=1; public MatrixView(Context context, AttributeSet attrs) { super(context, attrs); } public void setParentHeight(int height) { h = height; } @Override protected void dispatchDraw(Canvas canvas) { canvas.save(); int top = getTop(); float rotate = calculateAngel(top, h); float scale = calcuylateScale(top, h); Matrix m = canvas.getMatrix(); m.preTranslate(-2 / getWidth(), -2 / getHeight()); m.postScale(scale, scale); m.postTranslate(2 / getWidth(), 2 / getHeight()); m.postRotate(rotate); canvas.concat(m); super.dispatchDraw(canvas); canvas.restore(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } private float calculateAngel(int top, int h) { float result = 0f; if (top < h / 2f) { result = (top - (h / 2f)) / (h / 2f) * fullAngelFactor; } else if (top > h / 2f) { result = (top - (h / 2f)) / (h / 2f) * fullAngelFactor; } return result; } private float calcuylateScale(int top, int h) { float result = 0f; result = (1f - 1f/2f*Math.abs((top - h / 2f)) / (h / 2f)) * fullScaleFactor; return result; }}
private float fullAngelFactor 为旋转的角度
private float fullScaleFactor 为试图放大缩小的比例
private float fullAngelFactor=40f时:
主布局就补贴了,就是一个ListView
每一个Item
<?xml version="1.0" encoding="utf-8"?><com.wjj.test.MatrixView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <com.wjj.test.RoundImageView android:id="@+id/image" android:layout_width="80dp" android:layout_height="80dp" android:layout_marginLeft="30dp" android:scaleType="centerCrop" /> <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="80dp" android:gravity="left|center_vertical" android:paddingLeft="20dp" android:textSize="18sp" /></com.wjj.test.MatrixView>
具体实现可以看代码,附上源码下载地址:http://yunpan.cn/cmy9fi3fMDY7U 访问密码 0982
部分代码来源于互联网,如有重复请见谅
更多相关文章
- Android(安卓)Studio中两个模拟器互发短信的解决方案
- android中使用代码适配屏幕,dp与px互转、sp与px互转
- Android(安卓)的 dex2jar 和 jd-gui 反编译 apk 源代码
- android client随机验证码生成函数
- Android7.0之安装apk文件
- 获得android手机的联网状态
- Android(安卓)Arduino 蓝牙模块通信源代码
- Button按钮的单击事件
- Android(安卓)studio2.3.2 配置kotlin、Anko