700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android插件化开发指南——实践之仿酷狗音乐首页(自定义ImageView控件)

Android插件化开发指南——实践之仿酷狗音乐首页(自定义ImageView控件)

时间:2021-12-27 02:11:40

相关推荐

Android插件化开发指南——实践之仿酷狗音乐首页(自定义ImageView控件)

文章目录

1. 前言2. 基础环境——实现RecyclerView的网格布局3. 自定义ImageView3. 后记

1. 前言

拟定实现效果部分为下图的歌单列表部分,也就是图中红线框出来的部分。为了方便这里使用RecyclerView来进行实现,对于图中所需要的正方形图片显示控件,这里就考虑使用自定义的ImageView

2. 基础环境——实现RecyclerView的网格布局

首先在xml文件中定义RecyclerView

<androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/fx_music_song_list_below_time"android:layout_width="match_parent"android:layout_height="wrap_content"android:paddingLeft="8dp"android:paddingRight="8dp"/>

然后定义每个item的布局显示样式的布局文件,这里我定义为fx_music_song_list_below_time_item.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"xmlns:app="/apk/res-auto"android:orientation="vertical"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><!-- 自定义ImageView--><com.weizu.mymusicdemo.customcomponents.RoundEqualWidthImageViewandroid:id="@+id/fx_music_song_list_below_time_item_img"android:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/fx_music_rmdt_play"android:background="@drawable/fx_music_round_bg"android:scaleType="centerCrop"app:radius="8dp"/><LinearLayoutandroid:layout_width="200dp"android:layout_height="25dp"android:gravity="center"android:orientation="horizontal"android:layout_alignBottom="@id/fx_music_song_list_below_time_item_img"><ImageViewandroid:layout_width="0dp"android:layout_height="20dp"android:layout_weight="1"android:src="@drawable/fx_music_song_list_below_time_item_play"/><TextViewandroid:id="@+id/fx_music_song_list_below_time_item_play_number"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="2"android:text="123万"android:textColor="@color/white"android:gravity="left|center_vertical"android:textSize="12sp"/></LinearLayout></RelativeLayout><TextViewandroid:id="@+id/fx_music_song_list_below_time_item_intro"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="8dp"android:text="123万"android:textSize="12sp"android:textColor="@color/black"/></LinearLayout>

最后进行定义一个适配器,用来加载数据到具体的item项:

public class FxPageMusicSongListBelowTimeRecycleViewAdapter<T extends FxPageSongListItemBean> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {private Context mContext;private int mRescourseId;private List<T> mData;public FxPageMusicSongListBelowTimeRecycleViewAdapter(Context context, int rescourseId, List<T> data) {this.mContext = context;this.mRescourseId = rescourseId;this.mData = data;}@NonNull@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {// 实例化对应的子项xml文件View rootView = LayoutInflater.from(mContext).inflate(mRescourseId, parent, false);return new MyViewHolder(rootView);}@Overridepublic void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {MyViewHolder myViewHolder = (MyViewHolder) holder;// 设置数据到每个子项FxPageSongListItemBean bean = (FxPageSongListItemBean) mData.get(position);Glide.with(mContext).load(bean.getCoverImageUrl()).into(myViewHolder.coverImageView);myViewHolder.playNumber.setText(bean.getPlayNumber());myViewHolder.introduce.setText(bean.getIntroduceInfo());}@Overridepublic int getItemCount() {return mData.size();}static class MyViewHolder extends RecyclerView.ViewHolder{private ImageView coverImageView;private TextView playNumber;private TextView introduce;public MyViewHolder(@NonNull View itemView) {super(itemView);coverImageView = itemView.findViewById(R.id.fx_music_song_list_below_time_item_img);playNumber = itemView.findViewById(R.id.fx_music_song_list_below_time_item_play_number);introduce = itemView.findViewById(R.id.fx_music_song_list_below_time_item_intro);}}}

当然最后一步就是使用了,就是实例化适配器对象,得到RecyclerView实例。然后设置网格布局管理器,并简单设置一下间距:

FxPageMusicSongListBelowTimeRecycleViewAdapter<FxPageSongListItemBean> adapter =new FxPageMusicSongListBelowTimeRecycleViewAdapter<>(getContext(), R.layout.fx_music_song_list_below_time_item, beans);GridLayoutManager manager = new GridLayoutManager(getContext(), 3);recyclerView.setLayoutManager(manager);// 设置Item的间距recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {@Overridepublic void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {super.getItemOffsets(outRect, view, parent, state);outRect.left = 8;outRect.right = 8;outRect.top = 16;outRect.bottom = 16;}});recyclerView.setAdapter(adapter);

效果:

但是很容易发现一点就是,每个图片的底部的显示的人数部分这里看不清。其实观看原图可以发现在酷狗音乐中其实是使用了一个暗色的背景在底部。所以这里我将在自定义ImageView的时候,加上一层暗色的背景渐变。那么,接下来就进入本篇博客的正题,即:自定义ImageView控件。

3. 自定义ImageView

其实在前面的xml布局文件中可以看见,这里自定义的ImageViewcom.weizu.mymusicdemo.customcomponents.RoundEqualWidthImageView类,且圆角半径radius为自定义属性。

圆角可以使用canvas的裁剪工具来实现;遮罩层的暗色渐变可以使用在其上再绘制一张图片;在测量的时候设置宽度一样,就可以得到正方形;设置缩放类型,使它中心裁剪,填充满;

那么可以定义为:

public class RoundEqualWidthImageView extends AppCompatImageView {private int width;private int height;private int roundDp;public RoundEqualWidthImageView(Context context) {super(context);}public RoundEqualWidthImageView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);initData(context, attrs);}private void initData(Context context, AttributeSet attrs) {TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.roundEqualWidthImageView);// 默认为直角,没有弧度roundDp = array.getDimensionPixelOffset(R.styleable.roundEqualWidthImageView_radius, 0);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);width = getWidth();height = getHeight();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, widthMeasureSpec); // 设置宽度一样}@Overrideprotected void onDraw(Canvas canvas) {// 设置缩放类型setScaleType(ScaleType.CENTER_CROP);if (width < roundDp || height < roundDp) roundDp = 5;Path path = new Path();// 四个圆角裁剪path.moveTo(roundDp, 0);path.lineTo(width - roundDp, 0);path.quadTo(width, 0, width, roundDp);path.lineTo(width, height - roundDp);path.quadTo(width, height, width - roundDp, height);path.lineTo(roundDp, height);path.quadTo(0, height, 0, height - roundDp);path.lineTo(0, roundDp);path.quadTo(0, 0, roundDp, 0);canvas.clipPath(path);super.onDraw(canvas);// 绘制暗色渐变Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fx_music_song_list_below_time_item_cover_bg, null);canvas.drawBitmap(bitmap, 0, 0, null);}}

对于另一个圆角半径属性,这里新建一个values/attrs.xml

<?xml version="1.0" encoding="utf-8"?><resources><declare-styleable name="roundEqualWidthImageView"><attr name="radius" format="dimension"/></declare-styleable></resources>

那么在使用的时候,就简单指定基本属性和圆角半径即可:

<LinearLayoutxmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"xmlns:app="/apk/res-auto"android:orientation="vertical"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><com.weizu.mymusicdemo.customcomponents.RoundEqualWidthImageViewandroid:id="@+id/fx_music_song_list_below_time_item_img"android:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/fx_music_rmdt_play"app:radius="8dp"/>...</RelativeLayout></LinearLayout>

现在效果:

同样的为了记录,这部分代码我上传到了github:mymusicdemo-03。

3. 后记

在加载图片的时候使用的Glide的加载 ,突然想起了之前自己写的部分单/多线程断点下载的简单封装,感觉空了可以研究下如何继续深入下去。

References

mymusicdemo-03

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。