0. 效果图
效果图顺次为发现界面顶部,蕴含首页轮播图,程度滚动的按钮,举荐歌单;而后是发现界面举荐单曲,点击单曲就是间接进入播放界面;最初是全局播放管制条上点击播放列表按钮显示的播放列表弹窗。
1. 整体剖析
整体应用 RecycerView 实现,每个不同的块是一个 Item,例如:轮播图是一个 Item,按钮也是,举荐歌单和上面的歌单是,举荐单曲,还有最初的自定义首页那块也是一样。
提醒:之所以把举荐歌单上面的歌单和举荐歌单题目放一个 Item,次要是首页要实现自定义程序性能,更方便管理。
2. 轮播图
2.1 布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="wrap_content"
android:layout_margin="@dimen/padding_outer">
<com.youth.banner.Banner
android:id="@+id/banner"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="H,0.389"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
2.2 显示数据
//banner
BannerData data = (BannerData) d;
Banner bannerView = holder.getView(R.id.banner);
BannerImageAdapter<Ad> bannerImageAdapter = new BannerImageAdapter<Ad>(data.getData()) {
@Override
public void onBindView(BannerImageHolder holder, Ad data, int position, int size) {ImageUtil.show(getContext(), (ImageView) holder.itemView, data.getIcon());
}
};
bannerView.setAdapter(bannerImageAdapter);
bannerView.setOnBannerListener(onBannerListener);
bannerView.setBannerRound(DensityUtil.dip2px(getContext(), 10));
// 增加生命周期观察者
bannerView.addBannerLifecycleObserver(fragment);
bannerView.setIndicator(new CircleIndicator(getContext()));
按钮
3.1 布局
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="@dimen/padding_outer"
android:scrollbars="none">
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingHorizontal="@dimen/padding_meddle">
</LinearLayout>
</HorizontalScrollView>
3.2 显示数据
LinearLayout container = holder.getView(R.id.container);
if (container.getChildCount() > 0) {
// 曾经增加了
return;
}
// 横向显示 5 个半
float containerWidth = ScreenUtil.getScreenWith(container.getContext()) - DensityUtil.dip2px(container.getContext(), 10 * 2);
int itemWidth = (int) (containerWidth / 5.5);
DiscoveryButtonBinding binding;
LinearLayout.LayoutParams layoutParams;
for (IconTitleButtonData it : data.getData()) {binding = DiscoveryButtonBinding.inflate(LayoutInflater.from(getContext()));
binding.icon.setImageResource(it.getIcon());
binding.title.setText(it.getTitle());
if (it.getIcon() == R.drawable.day_recommend) {SuperViewUtil.show(binding.more);
// 显示日期
binding.more.setText(String.valueOf(SuperDateUtil.currentDay()));
}
// 设置点击事件
binding.getRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {}});
layoutParams = new LinearLayout.LayoutParams(itemWidth, ViewGroup.LayoutParams.WRAP_CONTENT);
container.addView(binding.getRoot(), layoutParams);
}
4. 举荐歌单
4.1 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="@layout/item_discovery_title" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="@dimen/padding_outer"
android:paddingBottom="@dimen/d5" />
</LinearLayout>
4.2 显示数据
private void bindSheetData(BaseViewHolder holder, SheetData data) {
// 设置题目,将题目放到每个具体的 item 上,益处是不便整体排序
holder.setText(R.id.title, R.string.recommend_sheet);
// 显示更多容器
holder.setVisible(R.id.more, true);
holder.getView(R.id.more).setOnClickListener(v -> {});
RecyclerView listView = holder.getView(R.id.list);
if (listView.getAdapter() == null) {
// 设置显示 3 列
GridLayoutManager layoutManager = new GridLayoutManager(listView.getContext(), 3);
listView.setLayoutManager(layoutManager);
sheetAdapter = new SheetAdapter(R.layout.item_sheet);
//item 点击
sheetAdapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {if (discoveryAdapterListener != null) {discoveryAdapterListener.onSheetClick((Sheet) adapter.getItem(position));
}
}
});
listView.setAdapter(sheetAdapter);
GridDividerItemDecoration itemDecoration = new GridDividerItemDecoration(getContext(), (int) DensityUtil.dip2px(getContext(), 5F));
listView.addItemDecoration(itemDecoration);
}
sheetAdapter.setNewInstance(data.getData());
}
5. 底部
5.1 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="@dimen/padding_outer"
android:gravity="center_horizontal"
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:id="@+id/refresh_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/refresh"
android:gravity="center_vertical"
android:text="@string/click_refresh"
android:textColor="@color/link"
android:textSize="@dimen/text_small" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/padding_small"
android:text="@string/change_content"
android:textColor="@color/black80"
android:textSize="@dimen/text_small" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.google.android.material.button.MaterialButton
android:id="@+id/custom"
style="@style/Widget.MaterialComponents.Button.UnelevatedButton"
android:layout_width="wrap_content"
android:layout_height="@dimen/d30"
android:layout_marginTop="@dimen/padding_outer"
android:backgroundTint="?attr/colorSurface"
android:insetTop="0dp"
android:insetBottom="0dp"
android:text="@string/custom_discovery"
android:textColor="@color/black80"
android:textSize="@dimen/text_small"
app:cornerRadius="@dimen/d15"
app:elevation="0dp"
app:strokeColor="@color/black80"
app:strokeWidth="@dimen/d0_5" />
</LinearLayout>
5.2 显示数据
holder.getView(R.id.refresh_button).setOnClickListener(v -> discoveryAdapterListener.onRefreshClick());
holder.getView(R.id.custom).setOnClickListener(v -> discoveryAdapterListener.onCustomDiscoveryClick());
6. 迷你管制条
他是一个自定义 Fragment,哪里要显示就放到哪里就行了。
7. 播放列表弹窗
/**
* 播放列表对话框
*/
public class MusicPlayListDialogFragment extends BaseViewModelBottomSheetDialogFragment<FragmentDialogAudioPlayListBinding> {
...
@Override
protected void initListeners() {super.initListeners();
// 删除所有按钮点击
binding.deleteAll.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 敞开对话框
dismiss();
// 删除全副音乐
getMusicListManager().deleteAll();
}
});
//item 中子控件点击
// 删除按钮点击
adapter.addChildClickViewIds(R.id.delete);
adapter.setOnItemChildClickListener(new OnItemChildClickListener() {
@Override
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
// 因为这里只有一个按钮点击
// 所以能够不判断
if (R.id.delete == view.getId()) {
// 删除按钮点击
removeItem(position);
}
}
});
// 循环模式点击
binding.loopModel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 更改循环模式
getMusicListManager().changeLoopModel();
// 显示循环模式
showLoopModel();}
});
// 设置 item 点击事件
adapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
// 敞开 dialog
// 能够依据具体的业务逻辑来决定是否敞开
dismiss();
// 播放点击的这首音乐
getMusicListManager().play(getMusicListManager().getDatum().get(position));
}
});
}
private void removeItem(int position) {adapter.removeAt(position);
// 从列表管理器中删除
getMusicListManager().delete(position);
showCount();}
/**
* 显示循环模式
*/
private void showLoopModel() {PlayListUtil.showLoopModel(getMusicListManager().getLoopModel(), binding.loopModel);
}
private void showCount() {binding.count.setText(String.format("(%d)", getMusicListManager().getDatum().size()));
}
}
感激你的浏览,更多文章请关注咱们,点击,评论,转发反对。