本篇主要记录新增discoverFragment(发现界面)及banner展示、以及使用lombok替代冗余的get、set方法等。
参考《Android使用GsomFormatPlus+Lombok简化定义实体类》
修改Login的实体类:
@NoArgsConstructor
@Data
public class LoginEntity {
private int loginType;
private int code;
private AccountEntity account;
private String token;
private ProfileEntity profile;
private List<BindingsEntity> bindings;
private String cookie;
@NoArgsConstructor
@Data
public static class AccountEntity {
private int id;
private String userName;
private int type;
private int status;
private int whitelistAuthority;
private long createTime;
private String salt;
private int tokenVersion;
private int ban;
private int baoyueVersion;
private int donateVersion;
private int vipType;
private long viptypeVersion;
private boolean anonimousUser;
private boolean uninitialized;
}
@NoArgsConstructor
@Data
public static class ProfileEntity {
private String backgroundImgIdStr;
private int userId;
private String avatarImgIdStr;
private boolean followed;
private String backgroundUrl;
private String detailDescription;
private int userType;
private int vipType;
private int gender;
private int accountStatus;
private long avatarImgId;
private String nickname;
private long backgroundImgId;
private long birthday;
private int city;
private String avatarUrl;
private boolean defaultAvatar;
private int province;
private Object expertTags;
private ExpertsEntity experts;
private boolean mutual;
private Object remarkName;
private int authStatus;
private int djStatus;
private String description;
private String signature;
private int authority;
private String avatarImgId_str;
private int followeds;
private int follows;
private int eventCount;
private Object avatarDetail;
private int playlistCount;
private int playlistBeSubscribedCount;
@NoArgsConstructor
@Data
public static class ExpertsEntity {
}
}
@NoArgsConstructor
@Data
public static class BindingsEntity {
private int userId;
private String url;
private boolean expired;
private String tokenJsonStr;
private long bindingTime;
private int expiresIn;
private int refreshTime;
private long id;
private int type;
}
}
然后删除对应的Login_bean实体类,替换一下其他使用到的地方即可。
修改moudle的build文件新增cookie引用:
// CookieJar
implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
public class ApplicationContextProvider extends ContentProvider {
@SuppressLint("StaticFieldLeak")
public static Context context;
@Override
public boolean onCreate() {
context = getContext();
return false;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
}
然后再androidmanifest.xml的application中添加provider:
<provider
android:name=".ApplicationContextProvider"
android:authorities="${applicationId}.contextProvider"
android:exported="false" />
然后定义ContextProvider.java用来单例获取context:
public class ContextProvider {
@SuppressLint("StaticFieldLeak")
private static volatile ContextProvider instance;
private final Context mContext;
private ContextProvider(Context context) {
mContext = context;
}
/**
* 获取实例
*/
public static ContextProvider get() {
if (instance == null) {
synchronized (ContextProvider.class) {
if (instance == null) {
Context context = ApplicationContextProvider.context;
if (context == null) {
throw new IllegalStateException("context == null");
}
instance = new ContextProvider(context);
}
}
}
return instance;
}
/**
* 获取上下文
*/
public Context getContext() {
return mContext;
}
public Application getApplication() {
return (Application) mContext.getApplicationContext();
}
}
修改RetrofitUtils.java
:
public class RetrofitUtils {
/**
* 单例模式
*/
public static ApiService apiService;
public static ApiService getmApiUrl(){
if (apiService == null){
synchronized (RetrofitUtils.class){
if (apiService == null){
apiService = new RetrofitUtils().getRetrofit();
}
}
}
return apiService;
}
private ApiService getRetrofit() {
//初始化Retrofit
ApiService apiService = initRetrofit(initOkHttp()).create(ApiService.class);
return apiService;
}
private OkHttpClient initOkHttp() {
File cacheDir = ContextProvider.get().getContext().getCacheDir();
long cacheSize = 10L * 1024L * 1024L; // 10 MiB
ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(ContextProvider.get().getContext()));
return new OkHttpClient().newBuilder()
.readTimeout(Constant.DEFAULT_TIME, TimeUnit.SECONDS) //设置读取超时时间
.connectTimeout(Constant.DEFAULT_TIME, TimeUnit.SECONDS) //设置请求超时时间
.writeTimeout(Constant.DEFAULT_TIME, TimeUnit.SECONDS) //设置写入超时时间
.addInterceptor(new LogInterceptor()) //添加打印拦截器
.retryOnConnectionFailure(true) //设置出错进行重新连接
.cache(new Cache(cacheDir, cacheSize)) //cache
.cookieJar(cookieJar) //cookie
.build();
}
/**
* 初始化Retrofit
*/
@NonNull
private Retrofit initRetrofit(OkHttpClient client){
return new Retrofit.Builder()
.client(client)
.baseUrl(Constant.BaseUrl)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addCallAdapterFactory(LiveDataCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
}
修改activity_main.xml
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/home_drawer_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/boundary_gray"
tools:context=".ui.home.MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/view_top"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_60"
app:layout_constraintTop_toTopOf="parent"
android:background="@color/colorPrimary"
/>
<ImageView
android:id="@+id/home_top_left_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_home_top_menu"
app:layout_constraintTop_toTopOf="@id/view_top"
app:layout_constraintBottom_toBottomOf="@id/view_top"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_12" />
<ImageView
android:id="@+id/search"
android:layout_width="@dimen/dp_22"
android:layout_height="@dimen/dp_25"
android:layout_marginEnd="@dimen/dp_16"
app:layout_constraintEnd_toEndOf="parent"
android:src="@drawable/music_mike"
app:layout_constraintTop_toTopOf="@id/view_top"
app:layout_constraintBottom_toBottomOf="@id/view_top" />
<EditText
android:id="@+id/ed_search"
android:layout_width="@dimen/dp_0"
android:layout_height="@dimen/dp_30"
android:layout_marginStart="@dimen/dp_16"
android:layout_marginEnd="@dimen/dp_16"
app:layout_constraintStart_toEndOf="@id/home_top_left_btn"
app:layout_constraintEnd_toStartOf="@id/search"
app:layout_constraintTop_toTopOf="@id/view_top"
android:alpha="0.5"
android:textColor="@color/white"
android:paddingStart="@dimen/dp_8"
android:paddingEnd="@dimen/dp_8"
android:paddingTop="@dimen/dp_5"
android:paddingBottom="@dimen/dp_5"
app:layout_constraintBottom_toBottomOf="@id/view_top"
android:background="@drawable/bg_edit_search_gray" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/home_viewpager"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_0"
app:layout_constraintTop_toBottomOf="@id/view_top"
app:layout_constraintBottom_toTopOf="@id/bottom_nav" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav"
android:layout_width="match_parent"
android:background="?android:attr/windowBackground"
android:layout_height="@dimen/dp_60"
app:menu="@menu/bottom_nav"
app:itemRippleColor="@color/white"
app:labelVisibilityMode="labeled"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"
tools:ignore="RtlHardcoded" />
</androidx.drawerlayout.widget.DrawerLayout>
新增侧边栏按钮ic_home_top_menu.xml
:
<!--
~ Copyright (c) 2022 Station. All rights reserved.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="16">
<path
android:pathData="M0,16H24V14H0V16ZM0,2H24V0H0V2ZM0,9H24V7H0V9Z"
android:fillColor="#ffffff"
android:fillType="evenOdd" />
</vector>
新增editview的背景bg_edit_search_gray.xml
:
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_20" />
<solid android:color="@color/grays_66" />
</shape>
在res下新建menu文件夹然后新增bottom_nav.xml
:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/discoverFragment"
android:icon="@drawable/shape_discover_select"
android:title="@string/bottom_home" />
<item
android:id="@+id/podcastFragment"
android:icon="@drawable/shape_podcast_select"
android:title="@string/bottom_podcast" />
<item
android:id="@+id/myFragment"
android:icon="@drawable/shape_my_select"
android:title="@string/bottom_my" />
<item
android:id="@+id/userFragment"
android:icon="@drawable/shape_follow_select"
android:title="@string/bottom_follow" />
</menu>
其余主界面的图片资源包括底部菜单的shape文件都可以在百度网盘里面下载:
链接:https://pan.baidu.com/s/1l249MNrqRSyPq9Om_2aUgw
提取码:1234
我就不一一贴上去了。
public class MainActivity extends BaseActivity {
private ActivityMainBinding binding;
private NavigationBarView navigationBarView;
private ArrayList<Fragment> fragments;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this).get(MainViewModel.class);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
initFragment();
initView();
initObserver();
}
private void initFragment() {
fragments = new ArrayList<>();
fragments.add(new DiscoverFragment());
fragments.add(new PodcastFragment());
fragments.add(new MineFragment());
}
private void initObserver() {
}
@SuppressLint("NonConstantResourceId")
private void initView() {
navigationBarView = binding.bottomNav;
initViewPager();
setDrawMenu();
}
private void initViewPager() {
navigationBarView.setOnItemSelectedListener(item -> {
switch (item.getItemId()){
case R.id.discoverFragment:
binding.homeViewpager.setCurrentItem(0,true);
break;
case R.id.podcastFragment:
binding.homeViewpager.setCurrentItem(1,true);
break;
case R.id.myFragment:
binding.homeViewpager.setCurrentItem(2,true);
break;
}
return true;
});
binding.homeViewpager.setUserInputEnabled(false); //禁止滑动
binding.homeViewpager.setAdapter(new FragmentStateAdapter(this) {
@NonNull
@Override
public Fragment createFragment(int position) {
return fragments.get(position);
}
@Override
public int getItemCount() {
return fragments.size();
}
});
binding.homeViewpager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
binding.bottomNav.getMenu().getItem(position).setChecked(true);
}
});
}
@SuppressLint("NewApi")
private void setDrawMenu() {
binding.homeTopLeftBtn.setOnClickListener(view -> {
if (ClickUtil.enableClick()){
binding.homeDrawerMenu.openDrawer(GravityCompat.START);
}
});
binding.homeDrawerMenu.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
binding.homeDrawerMenu.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {}
@Override
public void onDrawerOpened(@NonNull View drawerView) {
binding.homeDrawerMenu.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
@Override
public void onDrawerClosed(@NonNull View drawerView) {
//binding.homeDrawerMenu.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
@Override
public void onDrawerStateChanged(int newState) {}
});
}
@Override
public void onBackPressed() {
super.onBackPressed();
if (binding.homeDrawerMenu.isDrawerOpen(GravityCompat.START)){
binding.homeDrawerMenu.closeDrawer(GravityCompat.START);
}else {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addCategory(Intent.CATEGORY_HOME);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<data>
<variable
name="vm"
type="com.tobery.personalmusic.ui.home.discover.DiscoverFragmentViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<View
android:id="@+id/view_title_bg"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_45"
app:layout_constraintTop_toTopOf="parent"
android:background="@color/colorPrimary"
/>
<View
android:layout_width="match_parent"
android:layout_height="@dimen/dp_95"
app:layout_constraintTop_toBottomOf="@id/view_title_bg"
android:background="@color/colorPrimary"
/>
<com.youth.banner.Banner
android:id="@+id/banner_img"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_160"
app:layout_constraintTop_toBottomOf="@id/view_title_bg"
android:layout_margin="@dimen/dp_16"
/>
<ImageView
android:id="@+id/img_recommend"
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_50"
android:src="@drawable/ic_daily_recommend"
android:layout_margin="@dimen/dp_16"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/banner_img"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorPrimary"
android:textSize="@dimen/sp_12"
android:text="@{vm.date}"
app:layout_constraintTop_toTopOf="@id/img_recommend"
app:layout_constraintBottom_toBottomOf="@id/img_recommend"
app:layout_constraintStart_toStartOf="@id/img_recommend"
app:layout_constraintEnd_toEndOf="@id/img_recommend"
/>
<TextView
android:id="@+id/tv_daily"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/dp_4"
android:text="@string/day_recommend"
android:textColor="@color/dark_grey"
app:layout_constraintTop_toBottomOf="@id/img_recommend"
app:layout_constraintStart_toStartOf="@id/img_recommend"
app:layout_constraintEnd_toEndOf="@id/img_recommend"
android:textSize="@dimen/sp_12" />
<ImageView
android:id="@+id/img_mine_fm"
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_50"
android:src="@drawable/ic_mine_fm"
android:layout_margin="@dimen/dp_16"
app:layout_constraintStart_toEndOf="@id/img_recommend"
app:layout_constraintTop_toBottomOf="@id/banner_img"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/dp_4"
android:text="@string/fm"
android:textColor="@color/dark_grey"
app:layout_constraintTop_toBottomOf="@id/img_mine_fm"
app:layout_constraintStart_toStartOf="@id/img_mine_fm"
app:layout_constraintEnd_toEndOf="@id/img_mine_fm"
android:textSize="@dimen/sp_12" />
<ImageView
android:id="@+id/img_playlist"
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_50"
android:src="@drawable/ic_playlist"
android:layout_margin="@dimen/dp_16"
app:layout_constraintStart_toEndOf="@id/img_mine_fm"
app:layout_constraintTop_toBottomOf="@id/banner_img"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/dp_4"
android:text="@string/playlist"
android:textColor="@color/dark_grey"
app:layout_constraintTop_toBottomOf="@id/img_playlist"
app:layout_constraintStart_toStartOf="@id/img_playlist"
app:layout_constraintEnd_toEndOf="@id/img_playlist"
android:textSize="@dimen/sp_12" />
<ImageView
android:id="@+id/img_rank"
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_50"
android:src="@drawable/ic_playlist"
android:layout_margin="@dimen/dp_16"
app:layout_constraintStart_toEndOf="@id/img_playlist"
app:layout_constraintTop_toBottomOf="@id/banner_img"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/dp_4"
android:text="@string/rank"
android:textColor="@color/dark_grey"
app:layout_constraintTop_toBottomOf="@id/img_rank"
app:layout_constraintStart_toStartOf="@id/img_rank"
app:layout_constraintEnd_toEndOf="@id/img_rank"
android:textSize="@dimen/sp_12" />
<ImageView
android:id="@+id/img_live"
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_50"
android:src="@drawable/ic_live"
android:layout_margin="@dimen/dp_16"
app:layout_constraintStart_toEndOf="@id/img_rank"
app:layout_constraintTop_toBottomOf="@id/banner_img"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/dp_4"
android:text="@string/live"
android:textColor="@color/dark_grey"
app:layout_constraintTop_toBottomOf="@id/img_live"
app:layout_constraintStart_toStartOf="@id/img_live"
app:layout_constraintEnd_toEndOf="@id/img_live"
android:textSize="@dimen/sp_12" />
<ImageView
android:id="@+id/img_radio"
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_50"
android:src="@drawable/ic_radio"
android:layout_margin="@dimen/dp_16"
app:layout_constraintStart_toEndOf="@id/img_live"
app:layout_constraintTop_toBottomOf="@id/banner_img"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/dp_4"
android:text="@string/radio"
android:textColor="@color/dark_grey"
app:layout_constraintTop_toBottomOf="@id/img_radio"
app:layout_constraintStart_toStartOf="@id/img_radio"
app:layout_constraintEnd_toEndOf="@id/img_radio"
android:textSize="@dimen/sp_12" />
<View
android:id="@+id/view_recommend"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_1"
android:layout_marginTop="@dimen/dp_12"
android:background="@color/boundary_gray"
app:layout_constraintTop_toBottomOf="@id/tv_daily"/>
<TextView
android:id="@+id/tv_recommend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_16"
android:text="@string/recommend_playlist"
android:textColor="@color/tv_black"
android:textSize="@dimen/sp_14"
android:textStyle="bold"
app:layout_constraintTop_toBottomOf="@id/view_recommend"
app:layout_constraintStart_toStartOf="parent"
/>
<TextView
android:id="@+id/tv_playlist_playground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dp_16"
android:layout_marginStart="@dimen/dp_15"
android:background="@drawable/bg_playlist_playground"
android:paddingLeft="@dimen/dp_15"
android:paddingTop="@dimen/dp_8"
android:paddingRight="@dimen/dp_15"
android:paddingBottom="@dimen/dp_8"
android:text="@string/playlist_playground"
android:textColor="@color/tv_gray_01"
android:textSize="@dimen/sp_11"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_recommend"
app:layout_constraintBottom_toBottomOf="@id/tv_recommend"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recommend_recycle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_12"
android:layout_marginStart="@dimen/dp_16"
app:layout_constraintTop_toBottomOf="@id/tv_recommend"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
添加轮播图引用:
//banner
implementation 'io.github.youth5201314:banner:2.2.2'
implementation "androidx.viewpager2:viewpager2:1.0.0"
关于轮播图使用可以参考《Android三方框架banner实现轮播图》
该页面所有图片资源可以在上面发的网盘链接的discoverFragment文件下找到:
修改ApiService类,添加轮播api:
@GET("banner")
// 首页轮播
LiveData<ApiResponse<banner_bean>> getBanner(@Query("type") int type);
public class DiscoverFragmentViewModel extends ViewModel {
public String date = Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "";
public LiveData<ApiResponse<banner_bean>> getBanner(){
return RetrofitUtils.getmApiUrl().getBanner(2);
}
}
public class banner_bean implements Serializable {
/**
* banners : [{"pic":"http://p1.music.126.net/t1_KzNb5-4LKRzGqYQA81A==/109951167565475950.jpg","titleColor":"blue","typeTitle":"独家策划","url":"https://y.music.163.com/m/at/62a071f79c36d0102fa27345","bannerId":"1655555430984479"}]
* code : 200
*/
private int code;
private List<BannersBean> banners;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public List<BannersBean> getBanners() {
return banners;
}
public void setBanners(List<BannersBean> banners) {
this.banners = banners;
}
public static class BannersBean implements Serializable {
/**
* pic : http://p1.music.126.net/t1_KzNb5-4LKRzGqYQA81A==/109951167565475950.jpg
* titleColor : blue
* typeTitle : 独家策划
* url : https://y.music.163.com/m/at/62a071f79c36d0102fa27345
* bannerId : 1655555430984479
*/
private String pic;
private String titleColor;
private String typeTitle;
private String url;
private String bannerId;
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public String getTitleColor() {
return titleColor;
}
public void setTitleColor(String titleColor) {
this.titleColor = titleColor;
}
public String getTypeTitle() {
return typeTitle;
}
public void setTypeTitle(String typeTitle) {
this.typeTitle = typeTitle;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getBannerId() {
return bannerId;
}
public void setBannerId(String bannerId) {
this.bannerId = bannerId;
}
}
public class DiscoverFragment extends Fragment {
private FragmentDiscoverBinding binding;
private DiscoverFragmentViewModel viewModel;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmentDiscoverBinding.inflate(inflater,container,false);
viewModel = new ViewModelProvider(this).get(DiscoverFragmentViewModel.class);
binding.setLifecycleOwner(this);
binding.setVm(viewModel);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initObserver();
}
private void initObserver() {
viewModel.getBanner().observe(getViewLifecycleOwner(), banner_beanApiResponse -> {
if (banner_beanApiResponse.getStatus() == Status.SUCCESS){
initData(banner_beanApiResponse.getData().getBanners());
}
});
}
private void initData(List<banner_bean.BannersBean> banners) {
binding.bannerImg.setAdapter(new bannerAdapter(banners))
.addBannerLifecycleObserver(getViewLifecycleOwner())
.setIntercept(false) //不拦截事件
.setBannerRound(10f)//圆角
.setIndicator(new RectangleIndicator(getContext())) //线条指示器
.setIndicatorHeight(5)
.setIndicatorWidth(6,6)//选中下宽度一致
.setIndicatorGravity(IndicatorConfig.Direction.CENTER)
.setOnBannerListener(new OnBannerListener() {
@Override
public void OnBannerClick(Object data, int position) {
}
});
}
}
新增banner布局文件banner_title_image.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:id="@+id/bannerImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
<TextView
android:id="@+id/bannerTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:ellipsize="marquee"
android:paddingEnd="@dimen/dp_5"
android:paddingBottom="@dimen/dp_1"
android:singleLine="true"
android:textColor="#ffffff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
public class bannerAdapter extends BannerAdapter<banner_bean.BannersBean, TitleHolder> {
public bannerAdapter(List<banner_bean.BannersBean> datas) {
super(datas);
}
@Override
public TitleHolder onCreateHolder(ViewGroup parent, int viewType) {
return new TitleHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.banner_title_image,parent,false));
}
@Override
public void onBindView(TitleHolder holder, banner_bean.BannersBean data, int position, int size) {
Glide.with(holder.imageView)
.load(data.getPic())
.thumbnail(Glide.with(holder.itemView)
.load(R.drawable.ic_banner_loading))
.into(holder.imageView);
holder.textView.setText(data.getTypeTitle());
}
}
class TitleHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public TextView textView;
public TitleHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.bannerImage);
textView = itemView.findViewById(R.id.bannerTitle);
}
}
其他几个fragment页面暂时复制DiscoverFragment。有问题欢迎批评指正,觉得不错的也请点个赞 谢谢。