Administrator
2021-11-04 f7d36b0f2c254a048905ae27c9e421427eb0f2c8
tablayout 框架   分页加载框架
8 files added
3 files renamed
12 files modified
574 ■■■■ changed files
app/src/main/java/com/duqing/missions/MainActivity.java 2 ●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/BaseAdapter.java 1 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/FragmentAdapter.java 2 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/activities/BaseActivity.java 13 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/activities/BaseLoadPageActivity.java 84 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/activities/BaseTabActivity.java 78 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/activities/BaseTitleBarActivity.java 6 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/activity.java 7 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/fragments/BaseFragment.java 17 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/fragments/BaseLoadPageFragment.java 93 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/fragments/BaseTabFragment.java 74 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/base/model/BaseLoadPageViewModel.java 15 ●●●●● 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/hall/HallFragment.java 37 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/hall/HallViewModel.java 12 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/hall/SubHallFragment.java 4 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/hall/SubHallViewModel.java 20 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/home/HomeFragment.java 45 ●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/home/HomeViewModel.java 15 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/ui/main/mine/MineFragment.java 9 ●●●●● patch | view | raw | blame | history
app/src/main/res/layout/fragment_hall.xml 4 ●●●● patch | view | raw | blame | history
app/src/main/res/layout/fragment_home.xml 2 ●●● patch | view | raw | blame | history
app/src/main/res/layout/layout_tab_viewpager.xml 32 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/duqing/missions/MainActivity.java
@@ -2,8 +2,8 @@
import androidx.viewpager2.widget.ViewPager2;
import com.duqing.missions.base.BaseActivity;
import com.duqing.missions.base.FragmentAdapter;
import com.duqing.missions.base.activities.BaseActivity;
import com.duqing.missions.databinding.ActivityMainBinding;
import com.duqing.missions.ui.main.hall.HallFragment;
import com.duqing.missions.ui.main.home.HomeFragment;
app/src/main/java/com/duqing/missions/base/BaseAdapter.java
@@ -11,6 +11,7 @@
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;
app/src/main/java/com/duqing/missions/base/FragmentAdapter.java
@@ -5,6 +5,8 @@
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import com.duqing.missions.base.fragments.BaseFragment;
import java.util.ArrayList;
import java.util.List;
app/src/main/java/com/duqing/missions/base/activities/BaseActivity.java
File was renamed from app/src/main/java/com/duqing/missions/base/BaseActivity.java
@@ -1,4 +1,4 @@
package com.duqing.missions.base;
package com.duqing.missions.base.activities;
import android.Manifest;
import android.app.AlertDialog;
@@ -26,6 +26,8 @@
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.viewbinding.ViewBinding;
import com.duqing.missions.MyApplication;
@@ -58,11 +60,13 @@
import okhttp3.ResponseBody;
/**
 * activity 封装
 * Created by Administrator on 2021/10/27 0027.
 */
public abstract class BaseActivity<B extends ViewBinding> extends AppCompatActivity {
public abstract class BaseActivity<B extends ViewBinding,VM extends ViewModel> extends AppCompatActivity {
    protected  B binding;
    protected  VM viewModel;
    protected String TAG ;
    public final String[] FILE_PERMISSIONS = new String []{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};
    public final String[] LOCATION_PERMISSIONS = new String []{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION};
@@ -106,10 +110,13 @@
        // get genericity "B"
        setStatusBarBgColor(R.color.white);
        setStatusBarTextColor(true);
        Class<B> entityClass = (Class<B>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        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();
        }
app/src/main/java/com/duqing/missions/base/activities/BaseLoadPageActivity.java
New file
@@ -0,0 +1,84 @@
package com.duqing.missions.base.activities;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;
import com.duqing.missions.base.BaseAdapter;
import com.duqing.missions.base.model.BaseLoadPageViewModel;
import com.duqing.missions.data.BasePageResult;
import com.scwang.smart.refresh.footer.ClassicsFooter;
import com.scwang.smart.refresh.header.ClassicsHeader;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;
import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
/**
 * Created by Administrator on 2021/11/4 0004.
 */
public abstract class BaseLoadPageActivity<B extends ViewBinding,VM extends BaseLoadPageViewModel,A extends BaseAdapter,D extends BasePageResult>
        extends BaseTitleBarActivity<B,VM>  implements OnRefreshLoadMoreListener {
    protected SmartRefreshLayout smartRefresh;
    protected RecyclerView recycler;
    final String TAG = "RecyclerFragment";
    protected A adapter;//适配器
    protected String url;//请求地址
    protected HashMap param;//参数
    protected int page=1;
    protected final int SIZE = 10;
    protected boolean isRefresh = false;//是否正在刷新
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Class<A> entityClass = (Class<A>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[2];
        try {
            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);
            recycler =  (RecyclerView) binding.getClass().getDeclaredField("recycler").get(binding);
            recycler.setLayoutManager(new LinearLayoutManager(mContext));
            recycler.setAdapter(adapter);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void finishFreshLoadmore(D result){
        if(result.code == 200){
            smartRefresh.setEnableRefresh(true);
            smartRefresh.finishRefresh();
            if(page == 1){
                adapter.getData().clear();
                adapter.setData(result.rows);
            }else{
                adapter.getData().addAll(result.rows);
                adapter.notifyDataSetChanged();
            }
            if(result.total <= adapter.getData().size()// 总数是否已经加载完
                    || result.rows.size() < SIZE // 最后一页数据的数量一般不满size
            ){//判断是否没有数据了
                smartRefresh.finishLoadMoreWithNoMoreData();
            }else {
                smartRefresh.finishLoadMore();
            }
        }else{
            smartRefresh.setEnableRefresh(true);
            smartRefresh.finishRefresh();
            smartRefresh.finishLoadMore();
        }
    }
    public A getAdapter() {
        return adapter;
    }
}
app/src/main/java/com/duqing/missions/base/activities/BaseTabActivity.java
New file
@@ -0,0 +1,78 @@
package com.duqing.missions.base.activities;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModel;
import androidx.viewbinding.ViewBinding;
import androidx.viewpager2.widget.ViewPager2;
import com.duqing.missions.base.FragmentAdapter;
import com.duqing.missions.base.fragments.BaseFragment;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * Created by Administrator on 2021/11/4 0004.
 */
public abstract class BaseTabActivity<B extends ViewBinding,VM extends ViewModel>  extends BaseActivity<B,VM> {
    TabLayout tabLayout;
    FragmentAdapter fragmentAdapter;
    List<String> tabTitles = new ArrayList<>();
    ViewPager2 viewPager2;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        fragmentAdapter = new FragmentAdapter(this);
        fragmentAdapter.setFragments(initFragments());
        setTabTitles(initTabTitles());
        //设置当前可见Item左右可见page数,次范围内不会被销毁
        //禁用预加载
        try {
            viewPager2 = (ViewPager2) binding.getClass().getDeclaredField("viewPager2").get(binding);
            tabLayout = (TabLayout) binding.getClass().getDeclaredField("tabLayout").get(binding);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        ;
        viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
        viewPager2.setAdapter(fragmentAdapter);
        viewPager2.setCurrentItem(0);
        viewPager2.setUserInputEnabled(false); //true:滑动,false:禁止滑动
        new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> tab.setText(tabTitles.get(position))).attach();
    }
    protected abstract List<String> initTabTitles();
    protected abstract List<BaseFragment> initFragments();
    protected List<String> getTabTitles(){
        return tabTitles;
    }
    public FragmentAdapter getFragmentAdapter() {
        return fragmentAdapter;
    }
    public void setTabTitles(List<String> tabTitles) {
        if(tabTitles == null){
            this.tabTitles.clear();
        }
        this.tabTitles = tabTitles;
    }
    public void setTabTitles(String[] tabTitles) {
        if(tabTitles == null){
            this.tabTitles.clear();
        }
        setTabTitles(new ArrayList<>(Arrays.asList(tabTitles)));
    }
}
app/src/main/java/com/duqing/missions/base/activities/BaseTitleBarActivity.java
File was renamed from app/src/main/java/com/duqing/missions/base/BaseTitleBarActivity.java
@@ -1,18 +1,20 @@
package com.duqing.missions.base;
package com.duqing.missions.base.activities;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModel;
import androidx.viewbinding.ViewBinding;
import com.duqing.missions.widgets.TitleBarView;
/**
 * 带有标题栏的activity封装
 * Created by Administrator on 2021/11/2 0002.
 */
public abstract class BaseTitleBarActivity<B extends ViewBinding> extends BaseActivity<B> {
public abstract class BaseTitleBarActivity<B extends ViewBinding,VM extends ViewModel> extends BaseActivity<B,VM> {
    TitleBarView titleBarView;
    @Override
app/src/main/java/com/duqing/missions/base/activity.java
New file
@@ -0,0 +1,7 @@
package com.duqing.missions.base;
/**
 * Created by Administrator on 2021/11/3 0003.
 */
public class activity {
}
app/src/main/java/com/duqing/missions/base/fragments/BaseFragment.java
File was renamed from app/src/main/java/com/duqing/missions/base/BaseFragment.java
@@ -1,4 +1,4 @@
package com.duqing.missions.base;
package com.duqing.missions.base.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
@@ -7,27 +7,36 @@
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.viewbinding.ViewBinding;
import com.duqing.missions.base.activities.BaseActivity;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
/**
 * fragment 封装
 * Created by Administrator on 2021/10/28 0028.
 */
public abstract class BaseFragment<B extends ViewBinding> extends Fragment {
public abstract class BaseFragment<B extends ViewBinding,VM extends ViewModel> extends Fragment {
    protected  BaseActivity activity;
    protected BaseActivity activity;
    protected  B binding;
    protected  VM viewModel;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        // get genericity "B"
        Class<B> entityClass = (Class<B>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        try {
            final ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
            Class<B> entityClass = (Class<B>) type.getActualTypeArguments()[0];
            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);
        } catch (Exception e) {
            e.printStackTrace();
        }
app/src/main/java/com/duqing/missions/base/fragments/BaseLoadPageFragment.java
New file
@@ -0,0 +1,93 @@
package com.duqing.missions.base.fragments;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;
import com.duqing.missions.base.BaseAdapter;
import com.duqing.missions.base.model.BaseLoadPageViewModel;
import com.duqing.missions.data.BasePageResult;
import com.scwang.smart.refresh.footer.ClassicsFooter;
import com.scwang.smart.refresh.header.ClassicsHeader;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;
import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
/**
 * 分页fragment 封装
 * Created by Administrator on 2021/11/3 0003.
 */
public abstract class BaseLoadPageFragment<B extends ViewBinding,VM extends BaseLoadPageViewModel,A extends BaseAdapter,D extends BasePageResult> extends BaseFragment<B,VM>
        implements OnRefreshLoadMoreListener {
    protected SmartRefreshLayout smartRefresh;
    protected RecyclerView recycler;
    final String TAG = "RecyclerFragment";
    protected A adapter;//适配器
    protected String url;//请求地址
    protected HashMap param;//参数
    protected int page=1;
    protected final int SIZE = 10;
    protected boolean isRefresh = false;//是否正在刷新
    @Override
    public void initViews() {
        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);
            recycler =  (RecyclerView) binding.getClass().getDeclaredField("recycler").get(binding);
            recycler.setLayoutManager(new LinearLayoutManager(getContext()));
            recycler.setAdapter(adapter);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
        page++;
        viewModel.onLoadMore();
    }
    @Override
    public void onRefresh(@NonNull RefreshLayout refreshLayout) {
        page = 1;
        viewModel.onRefresh();
    }
    private void finishFreshLoadmore(D result){
        if(result.code == 200){
            smartRefresh.setEnableRefresh(true);
            smartRefresh.finishRefresh();
            if(page == 1){
                adapter.getData().clear();
                adapter.setData(result.rows);
            }else{
                adapter.getData().addAll(result.rows);
                adapter.notifyDataSetChanged();
            }
            if(result.total <= adapter.getData().size()// 总数是否已经加载完
                    || result.rows.size() < SIZE // 最后一页数据的数量一般不满size
            ){//判断是否没有数据了
                smartRefresh.finishLoadMoreWithNoMoreData();
            }else {
                smartRefresh.finishLoadMore();
            }
        }else{
            smartRefresh.setEnableRefresh(true);
            smartRefresh.finishRefresh();
            smartRefresh.finishLoadMore();
        }
    }
    public A getAdapter() {
        return adapter;
    }
}
app/src/main/java/com/duqing/missions/base/fragments/BaseTabFragment.java
New file
@@ -0,0 +1,74 @@
package com.duqing.missions.base.fragments;
import androidx.lifecycle.ViewModel;
import androidx.viewbinding.ViewBinding;
import androidx.viewpager2.widget.ViewPager2;
import com.duqing.missions.base.FragmentAdapter;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * 带有tablayout fragment封装
 * Created by Administrator on 2021/11/3 0003.
 */
public abstract class BaseTabFragment<B extends ViewBinding,VM extends ViewModel> extends BaseFragment<B,VM> {
    TabLayout tabLayout;
    FragmentAdapter fragmentAdapter;
    List<String> tabTitles = new ArrayList<>();
    ViewPager2 viewPager2;
    @Override
    public void initViews() {
        fragmentAdapter = new FragmentAdapter(activity);
        fragmentAdapter.setFragments(initFragments());
        setTabTitles(initTabTitles());
        //设置当前可见Item左右可见page数,次范围内不会被销毁
        //禁用预加载
        try {
            viewPager2 = (ViewPager2) binding.getClass().getDeclaredField("viewPager2").get(binding);
            tabLayout = (TabLayout) binding.getClass().getDeclaredField("tabLayout").get(binding);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        ;
        viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
        viewPager2.setAdapter(fragmentAdapter);
        viewPager2.setCurrentItem(0);
        viewPager2.setUserInputEnabled(false); //true:滑动,false:禁止滑动
        new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> tab.setText(tabTitles.get(position))).attach();
    }
    protected abstract List<String> initTabTitles();
    protected abstract List<BaseFragment> initFragments();
    protected List<String> getTabTitles(){
        return tabTitles;
    }
    public FragmentAdapter getFragmentAdapter() {
        return fragmentAdapter;
    }
    public void setTabTitles(List<String> tabTitles) {
        if(tabTitles == null){
            this.tabTitles.clear();
        }
        this.tabTitles = tabTitles;
    }
    public void setTabTitles(String[] tabTitles) {
        if(tabTitles == null){
            this.tabTitles.clear();
        }
        setTabTitles(new ArrayList<>(Arrays.asList(tabTitles)));
    }
}
app/src/main/java/com/duqing/missions/base/model/BaseLoadPageViewModel.java
New file
@@ -0,0 +1,15 @@
package com.duqing.missions.base.model;
import androidx.lifecycle.ViewModel;
/**
 * 分页
 * Created by Administrator on 2021/11/3 0003.
 */
public abstract class BaseLoadPageViewModel extends ViewModel {
    public abstract void onRefresh();
    public abstract void onLoadMore();
}
app/src/main/java/com/duqing/missions/ui/login/view/LoginActivity.java
@@ -19,7 +19,7 @@
import androidx.lifecycle.ViewModelProvider;
import com.duqing.missions.R;
import com.duqing.missions.base.BaseTitleBarActivity;
import com.duqing.missions.base.activities.BaseTitleBarActivity;
import com.duqing.missions.databinding.ActivityLoginBinding;
app/src/main/java/com/duqing/missions/ui/main/hall/HallFragment.java
@@ -1,29 +1,25 @@
package com.duqing.missions.ui.main.hall;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.viewpager2.widget.ViewPager2;
import com.duqing.missions.base.BaseFragment;
import com.duqing.missions.base.FragmentAdapter;
import com.duqing.missions.base.fragments.BaseFragment;
import com.duqing.missions.base.fragments.BaseTabFragment;
import com.duqing.missions.databinding.FragmentHallBinding;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
public class HallFragment extends BaseFragment<FragmentHallBinding> {
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
    private HallViewModel hallViewModel;
public class HallFragment extends BaseTabFragment<FragmentHallBinding,HallViewModel> {
    @Override
    public void initViews() {
        hallViewModel = new ViewModelProvider(this).get(HallViewModel.class);
        hallViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
            }
        });
        super.initViews();
        final String[] titles = new String[]{"全部","人气","简单","高价"};
        final FragmentAdapter fragmentAdapter = new FragmentAdapter(activity);
        fragmentAdapter.addFragment(new SubHallFragment());
@@ -36,7 +32,7 @@
        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() {
        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]);
@@ -46,4 +42,19 @@
    }
    @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());
        list.add(new SubHallFragment());
        return list;
    }
}
app/src/main/java/com/duqing/missions/ui/main/hall/HallViewModel.java
@@ -1,19 +1,7 @@
package com.duqing.missions.ui.main.hall;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class HallViewModel extends ViewModel {
    private MutableLiveData<String> mText;
    public HallViewModel() {
        mText = new MutableLiveData<>();
        mText.setValue("This is dashboard fragment");
    }
    public LiveData<String> getText() {
        return mText;
    }
}
app/src/main/java/com/duqing/missions/ui/main/hall/SubHallFragment.java
@@ -1,12 +1,12 @@
package com.duqing.missions.ui.main.hall;
import com.duqing.missions.base.BaseFragment;
import com.duqing.missions.base.fragments.BaseFragment;
import com.duqing.missions.databinding.FragmentSubHallBinding;
/**
 * Created by Administrator on 2021/11/3 0003.
 */
public class SubHallFragment extends BaseFragment<FragmentSubHallBinding> {
public class SubHallFragment extends BaseFragment<FragmentSubHallBinding,SubHallViewModel> {
app/src/main/java/com/duqing/missions/ui/main/hall/SubHallViewModel.java
New file
@@ -0,0 +1,20 @@
package com.duqing.missions.ui.main.hall;
import com.duqing.missions.base.model.BaseLoadPageViewModel;
/**
 * Created by Administrator on 2021/11/3 0003.
 */
public class SubHallViewModel extends BaseLoadPageViewModel {
    @Override
    public void onRefresh() {
    }
    @Override
    public void onLoadMore() {
    }
}
app/src/main/java/com/duqing/missions/ui/main/home/HomeFragment.java
@@ -8,83 +8,52 @@
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.duqing.missions.base.BaseFragment;
import com.duqing.missions.base.fragments.BaseLoadPageFragment;
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.MissionAdapter;
import com.duqing.missions.ui.main.home.adapter.MissionTopAdapter;
import com.duqing.missions.ui.main.home.model.MissionDesc;
import com.scwang.smart.refresh.footer.ClassicsFooter;
import com.scwang.smart.refresh.header.ClassicsHeader;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;
import java.util.List;
public class HomeFragment extends BaseFragment<FragmentHomeBinding> {
public class HomeFragment extends BaseLoadPageFragment<FragmentHomeBinding,HomeViewModel,MissionAdapter, BasePageResult<String>> {
    private HomeViewModel homeViewModel;
    final String TAG = "HomeFragment";
    @Override
    public void initViews() {
        homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
        super.initViews();
        binding.textSearch.setOnClickListener(v -> startActivity(new Intent(getContext(), LoginActivity.class)));
        final SmartRefreshLayout smartRefresh = binding.smartRefresh;
        smartRefresh.setRefreshHeader(new ClassicsHeader(getContext()));
        smartRefresh.setRefreshFooter(new ClassicsFooter(getContext()));
        final  TextView textView = binding.textRecommend;
        RecyclerView recyclerClassify = binding.recyclerClassify;
        RecyclerView recyclerTop = binding.recyclerTop;
        final RecyclerView recyclerRecommend = binding.recyclerRecommend;
        recyclerRecommend.setLayoutManager(new LinearLayoutManager(getContext()));
        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerClassify.setLayoutManager(layoutManager);
        recyclerTop.setLayoutManager(new GridLayoutManager(getContext(),3));
        smartRefresh.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() {
            @Override
            public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
                homeViewModel.onLoadMore();
            }
            @Override
            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                homeViewModel.onRefresh();
            }
        });
        final MissionTopAdapter topAdapter = new MissionTopAdapter();
        recyclerTop.setAdapter(topAdapter);
        final MissionAdapter recommendAdapter = new MissionAdapter();
        recyclerRecommend.setAdapter(recommendAdapter);
        homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                textView.setText(s);
            }
        });
        homeViewModel.getTopMissions().observe(getViewLifecycleOwner(), new Observer<List<MissionDesc>>() {
        viewModel.getTopMissions().observe(getViewLifecycleOwner(), new Observer<List<MissionDesc>>() {
            @Override
            public void onChanged(List<MissionDesc> missionDescs) {
                smartRefresh.finishRefresh();
                topAdapter.setData(missionDescs);
            }
        });
        homeViewModel.getRecommendMissions().observeForever(new Observer<List<MissionDesc>>() {
        viewModel.getRecommendMissions().observeForever(new Observer<List<MissionDesc>>() {
            @Override
            public void onChanged(List<MissionDesc> missionDescs) {
                smartRefresh.finishLoadMore();
                recommendAdapter.setData(missionDescs);
                adapter.setData(missionDescs);
            }
        });
    }
app/src/main/java/com/duqing/missions/ui/main/home/HomeViewModel.java
@@ -1,28 +1,21 @@
package com.duqing.missions.ui.main.home;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.duqing.missions.base.model.BaseLoadPageViewModel;
import com.duqing.missions.ui.main.home.model.MissionDesc;
import java.util.ArrayList;
import java.util.List;
public class HomeViewModel extends ViewModel {
public class HomeViewModel extends BaseLoadPageViewModel {
    private MutableLiveData<String> mText;
    private MutableLiveData<List<MissionDesc>> topMissions = new MutableLiveData<>();
    private MutableLiveData<List<MissionDesc>> recommendMissions = new MutableLiveData<>();
    public HomeViewModel() {
        mText = new MutableLiveData<>();
        mText.setValue("This is home fragment");
    }
    public LiveData<String> getText() {
        return mText;
    }
    public MutableLiveData<List<MissionDesc>> getTopMissions() {
        return topMissions;
@@ -32,7 +25,8 @@
        return recommendMissions;
    }
    public void onRefresh(){
    @Override
    public void onRefresh() {
        List<MissionDesc> list = topMissions.getValue() == null? new ArrayList<>() :topMissions.getValue();
        list.clear();
        list.add(new MissionDesc());
@@ -46,6 +40,7 @@
        recommendMissions.setValue(list2);
    }
    @Override
    public void onLoadMore(){
        List<MissionDesc> list = recommendMissions.getValue() == null? new ArrayList<>():recommendMissions.getValue() ;
        list.add(new MissionDesc());
app/src/main/java/com/duqing/missions/ui/main/mine/MineFragment.java
@@ -4,18 +4,17 @@
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.duqing.missions.base.BaseFragment;
import com.duqing.missions.base.fragments.BaseFragment;
import com.duqing.missions.databinding.FragmentMineBinding;
public class MineFragment extends BaseFragment<FragmentMineBinding> {
public class MineFragment extends BaseFragment<FragmentMineBinding,MineViewModel> {
    private MineViewModel notificationsViewModel;
    @Override
    public void initViews() {
        notificationsViewModel = new ViewModelProvider(this).get(MineViewModel.class);
        notificationsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
        viewModel = new ViewModelProvider(this).get(MineViewModel.class);
        viewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
            }
app/src/main/res/layout/fragment_hall.xml
@@ -8,7 +8,7 @@
    tools:context=".ui.main.hall.HallFragment" >
    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tablayout"
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/red"
@@ -26,7 +26,7 @@
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:nestedScrollingEnabled="false"
        app:layout_constraintTop_toBottomOf="@id/tablayout"
        app:layout_constraintTop_toBottomOf="@id/tabLayout"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />
app/src/main/res/layout/fragment_home.xml
@@ -153,7 +153,7 @@
                    android:textColor="@color/black"
                    android:layout_margin="@dimen/activity_horizontal_margin" />
                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/recycler_recommend"
                    android:id="@+id/recycler"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:overScrollMode="never"
app/src/main/res/layout/layout_tab_viewpager.xml
New file
@@ -0,0 +1,32 @@
<?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"
    tools:context=".ui.main.hall.HallFragment" >
    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMaxWidth="0dp"
        app:tabIndicatorFullWidth="false"
        app:tabSelectedTextColor="@color/white"
        app:tabTextColor="@color/enable"
        app:tabIndicatorColor="@color/white"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/view_pager_2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:nestedScrollingEnabled="false"
        app:layout_constraintTop_toBottomOf="@id/tabLayout"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>