Administrator
2021-11-05 462d583986e4739f7a75227b3fde4da587502ba5
主页 动态UI
adapter null视图问题修改
分页框架 include问题
7 files added
2 files renamed
1 files deleted
19 files modified
426 ■■■■■ changed files
app/src/main/java/com/duqing/missions/base/ViewModelFactory.java 33 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/activities/BaseActivity.java 10 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/activities/BaseLoadPageActivity.java 28 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/adapter/BaseAdapter.java 90 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/fragments/BaseFragment.java 7 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/fragments/BaseLoadPageFragment.java 26 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/common/NullViewHolder.java 18 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/login/view/LoginActivity.java 2 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/MainActivity.java 7 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/dynamic/DynamicFragment.java 38 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/dynamic/DynamicViewModel.java 9 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/hall/HallFragment.java 28 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/hall/SubHallFragment.java 11 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/home/HomeFragment.java 10 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/home/HomeViewModel.java 12 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/home/adapter/ClassifyAdapter.java 15 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/home/adapter/MissionAdapter.java 3 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/home/adapter/MissionTopAdapter.java 3 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/home/model/Classify.java 10 ●●●●● patch | view | raw | blame | history
app/src/main/res/drawable/ic_dynamic_black_24dp.xml patch | view | raw | blame | history
app/src/main/res/drawable/ic_hall_black_24dp.xml patch | view | raw | blame | history
app/src/main/res/drawable/ic_mine_black_24.xml 9 ●●●●● patch | view | raw | blame | history
app/src/main/res/layout/fragment_home.xml 4 ●●● patch | view | raw | blame | history
app/src/main/res/layout/fragment_sub_hall.xml 1 ●●●● patch | view | raw | blame | history
app/src/main/res/layout/home_item_classify.xml 9 ●●●●● patch | view | raw | blame | history
app/src/main/res/layout/item_square.xml 13 ●●●●● patch | view | raw | blame | history
app/src/main/res/layout/layout_null.xml 13 ●●●● patch | view | raw | blame | history
app/src/main/res/menu/bottom_nav_menu.xml 12 ●●●●● patch | view | raw | blame | history
app/src/main/res/values/strings.xml 5 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/ViewModelFactory.java
New file
@@ -0,0 +1,33 @@
package com.duqing.missions.base;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
/**
 * Created by Administrator on 2021/11/4 0004.
 */
public class ViewModelFactory implements ViewModelProvider.Factory {
    static ViewModelFactory sInstance;
    public static ViewModelFactory getInstance() {
        if (sInstance == null) {
            sInstance = new ViewModelFactory();
        }
        return sInstance;
    }
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        //noinspection TryWithIdenticalCatches
        try {
            return modelClass.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException("Cannot create an instance of " + modelClass, e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Cannot create an instance of " + modelClass, e);
        }
    }
}
app/src/main/java/com/duqing/missions/base/activities/BaseActivity.java
@@ -32,6 +32,7 @@
import com.duqing.missions.MyApplication;
import com.duqing.missions.R;
import com.duqing.missions.base.ViewModelFactory;
import com.duqing.missions.data.ApkUpGradeResult;
import com.duqing.missions.util.MyLog;
import com.duqing.missions.util.ResPonse;
@@ -110,16 +111,16 @@
        // get genericity "B"
        setStatusBarBgColor(R.color.white);
        setStatusBarTextColor(true);
        final ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
        try {
            final ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
            Class<B> entityClass = (Class<B>) type.getActualTypeArguments()[0];
            Method method = entityClass.getMethod("inflate", LayoutInflater.class);//get method from name "inflate";
            binding = (B) method.invoke(entityClass,getLayoutInflater());//execute method to create a objct of viewbind;
            Class<VM> vmClass = (Class<VM>) type.getActualTypeArguments()[1];
            viewModel = new ViewModelProvider(this).get(vmClass);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Class<VM> vmClass = (Class<VM>) type.getActualTypeArguments()[1];
        viewModel = new ViewModelProvider(this,getViewModelFactory()).get(vmClass);
        setContentView(binding.getRoot());
        mContext = this;
        try {
@@ -133,6 +134,9 @@
    public abstract void initViews();
    public ViewModelProvider.Factory getViewModelFactory(){
        return ViewModelFactory.getInstance();
    }
    public void setStatusBarTransparent(boolean isBlack){
        //透明状态栏
app/src/main/java/com/duqing/missions/base/activities/BaseLoadPageActivity.java
@@ -10,6 +10,7 @@
import com.duqing.missions.base.adapter.BaseAdapter;
import com.duqing.missions.base.model.BaseLoadPageViewModel;
import com.duqing.missions.data.BasePageResult;
import com.duqing.missions.databinding.RefreshRecyclerBinding;
import com.scwang.smart.refresh.footer.ClassicsFooter;
import com.scwang.smart.refresh.header.ClassicsHeader;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
@@ -37,19 +38,30 @@
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Class<A> entityClass = (Class<A>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2];
        try {
            Class<A> entityClass = (Class<A>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2];
            this.adapter = entityClass.newInstance();//实例化泛型
            smartRefresh = (SmartRefreshLayout) binding.getClass().getDeclaredField("smartRefresh").get(binding);
            smartRefresh.setRefreshHeader(new ClassicsHeader(mContext));
            smartRefresh.setRefreshFooter(new ClassicsFooter(mContext));
            smartRefresh.setOnRefreshLoadMoreListener(this);
            String smartStr = "smartRefresh";
            smartRefresh = (SmartRefreshLayout) binding.getClass().getField(smartStr).get(binding);
            recycler =  (RecyclerView) binding.getClass().getDeclaredField("recycler").get(binding);
            recycler.setLayoutManager(new LinearLayoutManager(mContext));
            recycler.setAdapter(adapter);
        } catch (Exception e) {
        } catch (NoSuchFieldException e) {
            try {
                RefreshRecyclerBinding includeRefreshRecycler = (RefreshRecyclerBinding) binding.getClass().getDeclaredField ("includeRefreshRecycler").get(binding);
                smartRefresh = includeRefreshRecycler.smartRefresh;
                recycler =  includeRefreshRecycler.recycler;
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (java.lang.InstantiationException e) {
            e.printStackTrace();
        }
        smartRefresh.setRefreshHeader(new ClassicsHeader(mContext));
        smartRefresh.setRefreshFooter(new ClassicsFooter(mContext));
        smartRefresh.setOnRefreshLoadMoreListener(this);
        recycler.setLayoutManager(new LinearLayoutManager(mContext));
        recycler.setAdapter(adapter);
    }
    private void finishFreshLoadmore(D result){
app/src/main/java/com/duqing/missions/base/adapter/BaseAdapter.java
@@ -2,17 +2,13 @@
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;
import com.duqing.missions.R;
import com.duqing.missions.base.activities.BaseActivity;
import com.duqing.missions.common.NullViewHolder;
import com.duqing.missions.databinding.LayoutNullBinding;
import com.duqing.missions.util.DeviceUtil;
@@ -26,14 +22,14 @@
 *  T  数据类型
 *  V 适配器视图
 */
public abstract class BaseAdapter<B extends ViewBinding,A extends BaseActivity,T> extends RecyclerView.Adapter {
public abstract class BaseAdapter<B extends ViewBinding,T> extends RecyclerView.Adapter {
    protected List<T> mData = new ArrayList<>();
    protected Drawable nullDrawable;
    protected String nullTxt="暂无数据";
    protected String TAG = "BaseAdapter";
    protected  A activity;
    protected BaseActivity activity;
    public BaseAdapter(){
    }
@@ -54,48 +50,38 @@
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // get genericity "B"
        Class<B> entityClass = (Class<B>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        try {
           /* for(Method method: entityClass.getMethods()){
                StringBuilder sb = new StringBuilder();
                for(Class type : method.getParameterTypes()){
                    sb.append(type.getSimpleName()+",");
                }
                Log.e(TAG,String.format("method:%s,return:%s,param:%s",method.getName(),method.getReturnType().getSimpleName(),sb.toString()));
            }*/
            Method method = entityClass.getMethod("inflate", LayoutInflater.class,ViewGroup.class,boolean.class);//get method from name "inflate";
            B vBind = (B) method.invoke(entityClass,LayoutInflater.from(parent.getContext()),parent,false);//execute method to create a objct of viewbind;
            return new ViewBindHolder(vBind);
        } catch (Exception e) {
            e.printStackTrace();
        if(viewType == 1 ){
            // get genericity "B"
            Class<B> entityClass = (Class<B>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
            try {
               /* for(Method method: entityClass.getMethods()){
                    StringBuilder sb = new StringBuilder();
                    for(Class type : method.getParameterTypes()){
                        sb.append(type.getSimpleName()+",");
                    }
                    Log.e(TAG,String.format("method:%s,return:%s,param:%s",method.getName(),method.getReturnType().getSimpleName(),sb.toString()));
                }*/
                Method method = entityClass.getMethod("inflate", LayoutInflater.class,ViewGroup.class,boolean.class);//get method from name "inflate";
                B vBind = (B) method.invoke(entityClass,LayoutInflater.from(parent.getContext()),parent,false);//execute method to create a objct of viewbind;
                return new ViewBindHolder(vBind);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return new NullViewHolder( LayoutNullBinding.inflate(LayoutInflater.from(parent.getContext())));
    }
    /**
     *
     * 创建视图
     * @param parent
     * @param layout  视图文件
     * @param viewType 视图类型   1 加载正常视图   其他则加载空数据
     * @return
     */
    protected View getRootView(@NonNull ViewGroup parent, @LayoutRes int layout,int viewType ){
        //MyLog.i(TAG,"getRootView viewType:"+viewType);
        return LayoutInflater.from(parent.getContext()).inflate(viewType==1?layout: R.layout.layout_null,parent,false);
        return new NullViewHolder( LayoutNullBinding.inflate(LayoutInflater.from(parent.getContext()),parent,false));
    }
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        //MyLog.i(TAG,"onBindViewHolder position:"+position+" "+mData.size()+" "+getItemViewType(position));
        if(getItemViewType(position)==0){
            return;
        if(activity == null){
            activity = (BaseActivity) holder.itemView.getContext();
        }
        try {
            activity = (A) holder.itemView.getContext();
        }catch (Exception e){}
        bindView((ViewBindHolder) holder,mData.size()==0?null:mData.get(position),position);
        if(getItemViewType(position)==0){
            bindView((NullViewHolder) holder);
        }else {
            bindView((ViewBindHolder) holder, mData.size() == 0 ? null : mData.get(position), position);
        }
    }
    /**
@@ -127,6 +113,10 @@
    protected abstract void bindView(ViewBindHolder holder,T data,int position);
    protected void bindView(NullViewHolder holder){
    }
    @Override
    public int getItemCount() {
        //默认显示空视图,若不显示空视图则重写该方法,返回mData.size()
@@ -138,17 +128,27 @@
    public int getItemViewType(int position) {
        //当下标为0,数据集合为0 返回0(意味当前应显示空数据视图))
        //MyLog.i(TAG,"getItemViewType position:"+position+" mdata:"+mData.size()+" "+(position ==0 && mData.size()==0));
        return position ==0 && mData.size()==0?0:1;
        return position == 0 && mData.size()==0?0:1;
    }
    public class ViewBindHolder extends RecyclerView.ViewHolder{
        B binding;
        public B binding;
        public ViewBindHolder( B binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }
    /**
     * 空数据显示
     * Created by Administrator on 2021/10/28 0028.
     */
    public class NullViewHolder extends RecyclerView.ViewHolder {
        LayoutNullBinding binding;
        public NullViewHolder(LayoutNullBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }
}
app/src/main/java/com/duqing/missions/base/fragments/BaseFragment.java
@@ -11,6 +11,7 @@
import androidx.lifecycle.ViewModelProvider;
import androidx.viewbinding.ViewBinding;
import com.duqing.missions.base.ViewModelFactory;
import com.duqing.missions.base.activities.BaseActivity;
import java.lang.reflect.Method;
@@ -36,13 +37,17 @@
            Method method = entityClass.getMethod("inflate", LayoutInflater.class,ViewGroup.class,boolean.class);//get method from name "inflate";
            binding = (B) method.invoke(entityClass,inflater,container,false);//execute method to create a objct of viewbind;
            Class<VM> vmClass = (Class<VM>) type.getActualTypeArguments()[1];
            viewModel = new ViewModelProvider(this).get(vmClass);
            viewModel = new ViewModelProvider(this,getViewModelFactory()).get(vmClass);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return binding.getRoot();
    }
    public ViewModelProvider.Factory getViewModelFactory(){
        return ViewModelFactory.getInstance();
    }
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
app/src/main/java/com/duqing/missions/base/fragments/BaseLoadPageFragment.java
@@ -8,6 +8,7 @@
import com.duqing.missions.base.adapter.BaseAdapter;
import com.duqing.missions.base.model.BaseLoadPageViewModel;
import com.duqing.missions.data.BasePageResult;
import com.duqing.missions.databinding.RefreshRecyclerBinding;
import com.scwang.smart.refresh.footer.ClassicsFooter;
import com.scwang.smart.refresh.header.ClassicsHeader;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
@@ -38,16 +39,27 @@
        try {
            Class<A> entityClass = (Class<A>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2];
            this.adapter = entityClass.newInstance();//实例化泛型
            smartRefresh = (SmartRefreshLayout) binding.getClass().getDeclaredField("smartRefresh").get(binding);
            smartRefresh.setRefreshHeader(new ClassicsHeader(getContext()));
            smartRefresh.setRefreshFooter(new ClassicsFooter(getContext()));
            smartRefresh.setOnRefreshLoadMoreListener(this);
            String smartStr = "smartRefresh";
            smartRefresh = (SmartRefreshLayout) binding.getClass().getField(smartStr).get(binding);
            recycler =  (RecyclerView) binding.getClass().getDeclaredField("recycler").get(binding);
            recycler.setLayoutManager(new LinearLayoutManager(getContext()));
            recycler.setAdapter(adapter);
        } catch (Exception e) {
        } catch (NoSuchFieldException e) {
            try {
                RefreshRecyclerBinding includeRefreshRecycler = (RefreshRecyclerBinding) binding.getClass().getDeclaredField ("includeRefreshRecycler").get(binding);
                smartRefresh = includeRefreshRecycler.smartRefresh;
                recycler =  includeRefreshRecycler.recycler;
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (java.lang.InstantiationException e) {
            e.printStackTrace();
        }
        smartRefresh.setRefreshHeader(new ClassicsHeader(getContext()));
        smartRefresh.setRefreshFooter(new ClassicsFooter(getContext()));
        smartRefresh.setOnRefreshLoadMoreListener(this);
        recycler.setLayoutManager(new LinearLayoutManager(getContext()));
        recycler.setAdapter(adapter);
    }
    @Override
app/src/main/java/com/duqing/missions/common/NullViewHolder.java
File was deleted
app/src/main/java/com/duqing/missions/ui/login/view/LoginActivity.java
@@ -32,6 +32,8 @@
        final EditText phoneEdit = binding.editPhone;
        final EditText passwordEditText = binding.editPassword;
        final Button loginButton = binding.login;
        viewModel.getLoginFormState().observe(this, new Observer<LoginFormState>() {
            @Override
            public void onChanged(@Nullable LoginFormState loginFormState) {
app/src/main/java/com/duqing/missions/ui/main/MainActivity.java
@@ -3,12 +3,14 @@
import androidx.viewpager2.widget.ViewPager2;
import com.duqing.missions.R;
import com.duqing.missions.base.adapter.FragmentAdapter;
import com.duqing.missions.base.activities.BaseActivity;
import com.duqing.missions.base.adapter.FragmentAdapter;
import com.duqing.missions.databinding.ActivityMainBinding;
import com.duqing.missions.ui.main.dynamic.DynamicFragment;
import com.duqing.missions.ui.main.hall.HallFragment;
import com.duqing.missions.ui.main.home.HomeFragment;
import com.duqing.missions.ui.main.mine.MineFragment;
import com.google.android.material.navigation.NavigationBarView;
public class MainActivity extends BaseActivity<ActivityMainBinding,MainViewModel> {
@@ -17,6 +19,7 @@
    public void initViews() {
        setStatusBarBgColor(R.color.red);
        setStatusBarTextColor(false);
        binding.navView.setLabelVisibilityMode(NavigationBarView.LABEL_VISIBILITY_LABELED);
        binding.navView.setOnItemSelectedListener(item -> {
            for(int i = 0 ; i < binding.navView.getMenu().size() ; i ++){
                if(item.getItemId() == binding.navView.getMenu().getItem(i).getItemId()){
@@ -29,6 +32,7 @@
        final FragmentAdapter fragmentAdapter = new FragmentAdapter(this);
        fragmentAdapter.addFragment(new HomeFragment());
        fragmentAdapter.addFragment(new HallFragment());
        fragmentAdapter.addFragment(new DynamicFragment());
        fragmentAdapter.addFragment(new MineFragment());
        //设置当前可见Item左右可见page数,次范围内不会被销毁
        //禁用预加载
@@ -44,6 +48,5 @@
        });
        binding.viewPager2.setCurrentItem(0);//设置默认第
    }
}
app/src/main/java/com/duqing/missions/ui/main/dynamic/DynamicFragment.java
New file
@@ -0,0 +1,38 @@
package com.duqing.missions.ui.main.dynamic;
import com.duqing.missions.R;
import com.duqing.missions.base.fragments.BaseFragment;
import com.duqing.missions.base.fragments.BaseTabFragment;
import com.duqing.missions.databinding.LayoutTabViewpagerBinding;
import com.duqing.missions.ui.main.hall.SubHallFragment;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * Created by Administrator on 2021/11/4 0004.
 */
public class DynamicFragment extends BaseTabFragment<LayoutTabViewpagerBinding,DynamicViewModel> {
    @Override
    public void initViews() {
        super.initViews();
        binding.tabLayout.setBackgroundColor(getResources().getColor(R.color.red));
    }
    @Override
    protected List<String> initTabTitles() {
        return new ArrayList<>(Arrays.asList(new String[]{"广场","活动","排行"}));
    }
    @Override
    protected List<BaseFragment> initFragments() {
        List<BaseFragment> list = new ArrayList<>();
        list.add(new SubHallFragment());
        list.add(new SubHallFragment());
        list.add(new SubHallFragment());
        return list;
    }
}
app/src/main/java/com/duqing/missions/ui/main/dynamic/DynamicViewModel.java
New file
@@ -0,0 +1,9 @@
package com.duqing.missions.ui.main.dynamic;
import androidx.lifecycle.ViewModel;
/**
 * Created by Administrator on 2021/11/4 0004.
 */
public class DynamicViewModel extends ViewModel {
}
app/src/main/java/com/duqing/missions/ui/main/hall/HallFragment.java
@@ -1,14 +1,9 @@
package com.duqing.missions.ui.main.hall;
import androidx.annotation.NonNull;
import androidx.viewpager2.widget.ViewPager2;
import com.duqing.missions.base.adapter.FragmentAdapter;
import com.duqing.missions.R;
import com.duqing.missions.base.fragments.BaseFragment;
import com.duqing.missions.base.fragments.BaseTabFragment;
import com.duqing.missions.databinding.LayoutTabViewpagerBinding;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import java.util.ArrayList;
import java.util.Arrays;
@@ -20,26 +15,7 @@
    @Override
    public void initViews() {
        super.initViews();
        final String[] titles = new String[]{"全部","人气","简单","高价"};
        final FragmentAdapter fragmentAdapter = new FragmentAdapter(activity);
        fragmentAdapter.addFragment(new SubHallFragment());
        fragmentAdapter.addFragment(new SubHallFragment());
        fragmentAdapter.addFragment(new SubHallFragment());
        fragmentAdapter.addFragment(new SubHallFragment());
        //设置当前可见Item左右可见page数,次范围内不会被销毁
        //禁用预加载
        binding.viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
        binding.viewPager2.setAdapter(fragmentAdapter);
        binding.viewPager2.setCurrentItem(0);
        binding.viewPager2.setUserInputEnabled(false); //true:滑动,false:禁止滑动
        TabLayoutMediator mediator = new TabLayoutMediator(binding.tabLayout, binding.viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
            @Override
            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
                tab.setText(titles[position]);
            }
        });
        mediator.attach();
        binding.tabLayout.setBackgroundColor(getResources().getColor(R.color.red));
    }
app/src/main/java/com/duqing/missions/ui/main/hall/SubHallFragment.java
@@ -1,17 +1,20 @@
package com.duqing.missions.ui.main.hall;
import com.duqing.missions.base.fragments.BaseFragment;
import com.duqing.missions.base.fragments.BaseLoadPageFragment;
import com.duqing.missions.data.BasePageResult;
import com.duqing.missions.databinding.FragmentSubHallBinding;
import com.duqing.missions.databinding.RefreshRecyclerBinding;
import com.duqing.missions.ui.main.home.adapter.MissionAdapter;
/**
 * Created by Administrator on 2021/11/3 0003.
 */
public class SubHallFragment extends BaseFragment<FragmentSubHallBinding,SubHallViewModel> {
public class SubHallFragment extends BaseLoadPageFragment<FragmentSubHallBinding,SubHallViewModel, MissionAdapter, BasePageResult<String>> {
    @Override
    public void initViews() {
        super.initViews();
        final RefreshRecyclerBinding includeRefreshRecycler = binding.includeRefreshRecycler;
    }
}
app/src/main/java/com/duqing/missions/ui/main/home/HomeFragment.java
@@ -18,8 +18,10 @@
import com.duqing.missions.data.BasePageResult;
import com.duqing.missions.databinding.FragmentHomeBinding;
import com.duqing.missions.ui.login.view.LoginActivity;
import com.duqing.missions.ui.main.home.adapter.ClassifyAdapter;
import com.duqing.missions.ui.main.home.adapter.MissionAdapter;
import com.duqing.missions.ui.main.home.adapter.MissionTopAdapter;
import com.duqing.missions.ui.main.home.model.Classify;
import com.duqing.missions.ui.main.home.model.MissionDesc;
import java.util.List;
@@ -39,6 +41,8 @@
        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerClassify.setLayoutManager(layoutManager);
        ClassifyAdapter classifyAdapter = new ClassifyAdapter();
        recyclerClassify.setAdapter(classifyAdapter);
        recyclerTop.setLayoutManager(new GridLayoutManager(getContext(),3));
        final MissionTopAdapter topAdapter = new MissionTopAdapter();
        recyclerTop.setAdapter(topAdapter);
@@ -56,6 +60,12 @@
                adapter.setData(missionDescs);
            }
        });
        viewModel.getClassifies().observeForever(new Observer<List<Classify>>() {
            @Override
            public void onChanged(List<Classify> cliassifies) {
                classifyAdapter.setData(cliassifies);
            }
        });
    }
    @Nullable
app/src/main/java/com/duqing/missions/ui/main/home/HomeViewModel.java
@@ -3,6 +3,7 @@
import androidx.lifecycle.MutableLiveData;
import com.duqing.missions.base.model.BaseLoadPageViewModel;
import com.duqing.missions.ui.main.home.model.Classify;
import com.duqing.missions.ui.main.home.model.MissionDesc;
import java.util.ArrayList;
@@ -12,10 +13,15 @@
    private MutableLiveData<List<MissionDesc>> topMissions = new MutableLiveData<>();
    private MutableLiveData<List<MissionDesc>> recommendMissions = new MutableLiveData<>();
    private MutableLiveData<List<Classify>> classifies = new MutableLiveData<>();
    public HomeViewModel() {
    }
    public MutableLiveData<List<Classify>> getClassifies() {
        return classifies;
    }
    public MutableLiveData<List<MissionDesc>> getTopMissions() {
        return topMissions;
@@ -38,6 +44,12 @@
        list2.clear();
        list2.addAll(list);
        recommendMissions.setValue(list2);
        List<Classify> list3 = classifies.getValue() == null? new ArrayList<>() :classifies.getValue();
        list3.add(new Classify());
        list3.add(new Classify());
        list3.add(new Classify());
        list3.add(new Classify());
        classifies.setValue(list3);
    }
    @Override
app/src/main/java/com/duqing/missions/ui/main/home/adapter/ClassifyAdapter.java
New file
@@ -0,0 +1,15 @@
package com.duqing.missions.ui.main.home.adapter;
import com.duqing.missions.base.adapter.BaseAdapter;
import com.duqing.missions.databinding.HomeItemClassifyBinding;
import com.duqing.missions.ui.main.home.model.Classify;
/**
 * Created by Administrator on 2021/11/5 0005.
 */
public class ClassifyAdapter extends BaseAdapter<HomeItemClassifyBinding,  Classify> {
    @Override
    protected void bindView(ViewBindHolder holder, Classify data, int position) {
        holder.binding.textView.setText("Text "+position);
    }
}
app/src/main/java/com/duqing/missions/ui/main/home/adapter/MissionAdapter.java
@@ -1,6 +1,5 @@
package com.duqing.missions.ui.main.home.adapter;
import com.duqing.missions.ui.main.MainActivity;
import com.duqing.missions.base.adapter.BaseAdapter;
import com.duqing.missions.databinding.HomtItemRecommendBinding;
import com.duqing.missions.ui.main.home.model.MissionDesc;
@@ -8,7 +7,7 @@
/**
 * Created by Administrator on 2021/10/29 0029.
 */
public class MissionAdapter extends BaseAdapter<HomtItemRecommendBinding, MainActivity, MissionDesc> {
public class MissionAdapter extends BaseAdapter<HomtItemRecommendBinding,  MissionDesc> {
    @Override
    protected void bindView(ViewBindHolder holder, MissionDesc data, int position) {
app/src/main/java/com/duqing/missions/ui/main/home/adapter/MissionTopAdapter.java
@@ -1,6 +1,5 @@
package com.duqing.missions.ui.main.home.adapter;
import com.duqing.missions.ui.main.MainActivity;
import com.duqing.missions.base.adapter.BaseAdapter;
import com.duqing.missions.databinding.HomeItemTopBinding;
import com.duqing.missions.ui.main.home.model.MissionDesc;
@@ -8,7 +7,7 @@
/**
 * Created by Administrator on 2021/10/28 0028.
 */
public class MissionTopAdapter extends BaseAdapter<HomeItemTopBinding, MainActivity, MissionDesc> {
public class MissionTopAdapter extends BaseAdapter<HomeItemTopBinding,  MissionDesc> {
    @Override
app/src/main/java/com/duqing/missions/ui/main/home/model/Classify.java
New file
@@ -0,0 +1,10 @@
package com.duqing.missions.ui.main.home.model;
/**
 * Created by Administrator on 2021/11/5 0005.
 */
public class Classify {
    String text,image;
}
app/src/main/res/drawable/ic_dynamic_black_24dp.xml
app/src/main/res/drawable/ic_hall_black_24dp.xml
app/src/main/res/drawable/ic_mine_black_24.xml
New file
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24" >
  <path
      android:fillColor="#FF000000"
      android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>
app/src/main/res/layout/fragment_home.xml
@@ -38,7 +38,9 @@
        android:layout_height="35dp"
        android:drawableLeft="@mipmap/icon_search"
        android:text="任务标题、编号"
        android:textColor="@color/gray"
        android:textColor="@color/white"
        android:drawableTint="@color/white"
        android:backgroundTint="@color/white"
        android:drawablePadding="10dp"
        android:background="@drawable/trans_gray_circle"
        android:gravity="center"
app/src/main/res/layout/fragment_sub_hall.xml
@@ -72,6 +72,7 @@
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
    <include layout="@layout/refresh_recycler"
        android:id="@+id/include_refresh_recycler"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/view"
app/src/main/res/layout/home_item_classify.xml
@@ -2,19 +2,18 @@
<LinearLayout 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_marginRight="@dimen/frame_margin_lr"
    android:layout_marginLeft="@dimen/frame_margin_lr"
    android:layout_marginTop="@dimen/frame_margin_lr"
    android:padding="@dimen/frame_margin_lr"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_width="100dp"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/img_icon"
        android:layout_width="50dp"
        android:layout_height="wrap_content"
        android:layout_height="50dp"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"
        tools:srcCompat="@tools:sample/avatars"/>
    <TextView
app/src/main/res/layout/item_square.xml
New file
@@ -0,0 +1,13 @@
<?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:background="@drawable/bg_white_corner"
    android:layout_marginTop="@dimen/activity_horizontal_margin"
    android:layout_marginLeft="@dimen/activity_horizontal_margin"
    android:layout_marginRight="@dimen/activity_horizontal_margin"
    android:elevation="@dimen/small_radios">
</LinearLayout>
app/src/main/res/layout/layout_null.xml
@@ -1,19 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
<RelativeLayout
    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:minHeight="400dp"
    android:layout_height="match_parent">
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="暂无数据"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:layout_gravity="center_horizontal" />
</RelativeLayout>
app/src/main/res/menu/bottom_nav_menu.xml
@@ -8,12 +8,16 @@
    <item
        android:id="@+id/navigation_hall"
        android:icon="@drawable/ic_dashboard_black_24dp"
        android:title="@string/title_dashboard"/>
        android:icon="@drawable/ic_hall_black_24dp"
        android:title="@string/title_hall"/>
    <item
        android:id="@+id/navigation_dynamic"
        android:icon="@drawable/ic_dynamic_black_24dp"
        android:title="@string/title_dynamic"/>
    <item
        android:id="@+id/navigation_mine"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:title="@string/title_notifications"/>
        android:icon="@drawable/ic_mine_black_24"
        android:title="@string/title_mine"/>
</menu>
app/src/main/res/values/strings.xml
@@ -1,8 +1,9 @@
<resources>
    <string name="app_name">Missions</string>
    <string name="title_home">Home</string>
    <string name="title_dashboard">Dashboard</string>
    <string name="title_notifications">Notifications</string>
    <string name="title_hall">Hall</string>
    <string name="title_dynamic">Dynamic</string>
    <string name="title_mine">Mine</string>
    <string name="prompt_email">Email</string>
    <string name="prompt_password">Password</string>
    <string name="action_sign_in">Sign in or register</string>