From f7d36b0f2c254a048905ae27c9e421427eb0f2c8 Mon Sep 17 00:00:00 2001 From: Administrator <123> Date: Thu, 04 Nov 2021 02:04:19 +0000 Subject: [PATCH] tablayout 框架 分页加载框架 --- app/src/main/java/com/duqing/missions/ui/main/hall/SubHallFragment.java | 4 app/src/main/java/com/duqing/missions/ui/main/hall/SubHallViewModel.java | 20 ++ app/src/main/java/com/duqing/missions/ui/main/hall/HallViewModel.java | 12 - app/src/main/java/com/duqing/missions/base/activities/BaseLoadPageActivity.java | 84 ++++++++ app/src/main/java/com/duqing/missions/base/activities/BaseActivity.java | 13 + app/src/main/java/com/duqing/missions/base/activities/BaseTabActivity.java | 78 +++++++ app/src/main/java/com/duqing/missions/base/fragments/BaseTabFragment.java | 74 +++++++ app/src/main/res/layout/fragment_home.xml | 2 app/src/main/java/com/duqing/missions/base/FragmentAdapter.java | 2 app/src/main/res/layout/layout_tab_viewpager.xml | 32 +++ app/src/main/java/com/duqing/missions/base/activity.java | 7 app/src/main/java/com/duqing/missions/base/fragments/BaseLoadPageFragment.java | 93 +++++++++ app/src/main/res/layout/fragment_hall.xml | 4 app/src/main/java/com/duqing/missions/base/BaseAdapter.java | 1 app/src/main/java/com/duqing/missions/ui/main/hall/HallFragment.java | 37 ++- app/src/main/java/com/duqing/missions/base/activities/BaseTitleBarActivity.java | 6 app/src/main/java/com/duqing/missions/ui/login/view/LoginActivity.java | 2 app/src/main/java/com/duqing/missions/base/fragments/BaseFragment.java | 17 + app/src/main/java/com/duqing/missions/base/model/BaseLoadPageViewModel.java | 15 + app/src/main/java/com/duqing/missions/ui/main/home/HomeFragment.java | 45 --- app/src/main/java/com/duqing/missions/ui/main/mine/MineFragment.java | 9 app/src/main/java/com/duqing/missions/MainActivity.java | 2 app/src/main/java/com/duqing/missions/ui/main/home/HomeViewModel.java | 15 - 23 files changed, 480 insertions(+), 94 deletions(-) diff --git a/app/src/main/java/com/duqing/missions/MainActivity.java b/app/src/main/java/com/duqing/missions/MainActivity.java index f903b3b..09a3b32 100644 --- a/app/src/main/java/com/duqing/missions/MainActivity.java +++ b/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; diff --git a/app/src/main/java/com/duqing/missions/base/BaseAdapter.java b/app/src/main/java/com/duqing/missions/base/BaseAdapter.java index 520e455..735ccef 100644 --- a/app/src/main/java/com/duqing/missions/base/BaseAdapter.java +++ b/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; diff --git a/app/src/main/java/com/duqing/missions/base/FragmentAdapter.java b/app/src/main/java/com/duqing/missions/base/FragmentAdapter.java index 9a4f646..3d5bb42 100644 --- a/app/src/main/java/com/duqing/missions/base/FragmentAdapter.java +++ b/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; diff --git a/app/src/main/java/com/duqing/missions/base/BaseActivity.java b/app/src/main/java/com/duqing/missions/base/activities/BaseActivity.java similarity index 96% rename from app/src/main/java/com/duqing/missions/base/BaseActivity.java rename to app/src/main/java/com/duqing/missions/base/activities/BaseActivity.java index 3d37b2c..ada8707 100644 --- a/app/src/main/java/com/duqing/missions/base/BaseActivity.java +++ b/app/src/main/java/com/duqing/missions/base/activities/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(); } diff --git a/app/src/main/java/com/duqing/missions/base/activities/BaseLoadPageActivity.java b/app/src/main/java/com/duqing/missions/base/activities/BaseLoadPageActivity.java new file mode 100644 index 0000000..ef17679 --- /dev/null +++ b/app/src/main/java/com/duqing/missions/base/activities/BaseLoadPageActivity.java @@ -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; + } +} diff --git a/app/src/main/java/com/duqing/missions/base/activities/BaseTabActivity.java b/app/src/main/java/com/duqing/missions/base/activities/BaseTabActivity.java new file mode 100644 index 0000000..1afd695 --- /dev/null +++ b/app/src/main/java/com/duqing/missions/base/activities/BaseTabActivity.java @@ -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))); + } +} diff --git a/app/src/main/java/com/duqing/missions/base/BaseTitleBarActivity.java b/app/src/main/java/com/duqing/missions/base/activities/BaseTitleBarActivity.java similarity index 90% rename from app/src/main/java/com/duqing/missions/base/BaseTitleBarActivity.java rename to app/src/main/java/com/duqing/missions/base/activities/BaseTitleBarActivity.java index 8a56999..dab729e 100644 --- a/app/src/main/java/com/duqing/missions/base/BaseTitleBarActivity.java +++ b/app/src/main/java/com/duqing/missions/base/activities/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 diff --git a/app/src/main/java/com/duqing/missions/base/activity.java b/app/src/main/java/com/duqing/missions/base/activity.java new file mode 100644 index 0000000..6a431e6 --- /dev/null +++ b/app/src/main/java/com/duqing/missions/base/activity.java @@ -0,0 +1,7 @@ +package com.duqing.missions.base; + +/** + * Created by Administrator on 2021/11/3 0003. + */ +public class activity { +} diff --git a/app/src/main/java/com/duqing/missions/base/BaseFragment.java b/app/src/main/java/com/duqing/missions/base/fragments/BaseFragment.java similarity index 65% rename from app/src/main/java/com/duqing/missions/base/BaseFragment.java rename to app/src/main/java/com/duqing/missions/base/fragments/BaseFragment.java index 099381b..882ed3d 100644 --- a/app/src/main/java/com/duqing/missions/base/BaseFragment.java +++ b/app/src/main/java/com/duqing/missions/base/fragments/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(); } diff --git a/app/src/main/java/com/duqing/missions/base/fragments/BaseLoadPageFragment.java b/app/src/main/java/com/duqing/missions/base/fragments/BaseLoadPageFragment.java new file mode 100644 index 0000000..327311a --- /dev/null +++ b/app/src/main/java/com/duqing/missions/base/fragments/BaseLoadPageFragment.java @@ -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; + } +} diff --git a/app/src/main/java/com/duqing/missions/base/fragments/BaseTabFragment.java b/app/src/main/java/com/duqing/missions/base/fragments/BaseTabFragment.java new file mode 100644 index 0000000..a70076a --- /dev/null +++ b/app/src/main/java/com/duqing/missions/base/fragments/BaseTabFragment.java @@ -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))); + } +} diff --git a/app/src/main/java/com/duqing/missions/base/model/BaseLoadPageViewModel.java b/app/src/main/java/com/duqing/missions/base/model/BaseLoadPageViewModel.java new file mode 100644 index 0000000..a4ef5f1 --- /dev/null +++ b/app/src/main/java/com/duqing/missions/base/model/BaseLoadPageViewModel.java @@ -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(); + +} diff --git a/app/src/main/java/com/duqing/missions/ui/login/view/LoginActivity.java b/app/src/main/java/com/duqing/missions/ui/login/view/LoginActivity.java index d10b2eb..551e4c9 100644 --- a/app/src/main/java/com/duqing/missions/ui/login/view/LoginActivity.java +++ b/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; diff --git a/app/src/main/java/com/duqing/missions/ui/main/hall/HallFragment.java b/app/src/main/java/com/duqing/missions/ui/main/hall/HallFragment.java index 325e471..9127bf2 100644 --- a/app/src/main/java/com/duqing/missions/ui/main/hall/HallFragment.java +++ b/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; + } } \ No newline at end of file diff --git a/app/src/main/java/com/duqing/missions/ui/main/hall/HallViewModel.java b/app/src/main/java/com/duqing/missions/ui/main/hall/HallViewModel.java index ecbe20f..85ac968 100644 --- a/app/src/main/java/com/duqing/missions/ui/main/hall/HallViewModel.java +++ b/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; - } } \ No newline at end of file diff --git a/app/src/main/java/com/duqing/missions/ui/main/hall/SubHallFragment.java b/app/src/main/java/com/duqing/missions/ui/main/hall/SubHallFragment.java index 3a3c00e..f8fbc44 100644 --- a/app/src/main/java/com/duqing/missions/ui/main/hall/SubHallFragment.java +++ b/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> { diff --git a/app/src/main/java/com/duqing/missions/ui/main/hall/SubHallViewModel.java b/app/src/main/java/com/duqing/missions/ui/main/hall/SubHallViewModel.java new file mode 100644 index 0000000..2407707 --- /dev/null +++ b/app/src/main/java/com/duqing/missions/ui/main/hall/SubHallViewModel.java @@ -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() { + + } +} diff --git a/app/src/main/java/com/duqing/missions/ui/main/home/HomeFragment.java b/app/src/main/java/com/duqing/missions/ui/main/home/HomeFragment.java index 346c357..2b6198a 100644 --- a/app/src/main/java/com/duqing/missions/ui/main/home/HomeFragment.java +++ b/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); } }); } diff --git a/app/src/main/java/com/duqing/missions/ui/main/home/HomeViewModel.java b/app/src/main/java/com/duqing/missions/ui/main/home/HomeViewModel.java index eb69ae9..6852983 100644 --- a/app/src/main/java/com/duqing/missions/ui/main/home/HomeViewModel.java +++ b/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()); diff --git a/app/src/main/java/com/duqing/missions/ui/main/mine/MineFragment.java b/app/src/main/java/com/duqing/missions/ui/main/mine/MineFragment.java index 88e886b..3eb8f5e 100644 --- a/app/src/main/java/com/duqing/missions/ui/main/mine/MineFragment.java +++ b/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) { } diff --git a/app/src/main/res/layout/fragment_hall.xml b/app/src/main/res/layout/fragment_hall.xml index de2e2f9..433a3f7 100644 --- a/app/src/main/res/layout/fragment_hall.xml +++ b/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" /> diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 3ad528c..60925d1 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/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" diff --git a/app/src/main/res/layout/layout_tab_viewpager.xml b/app/src/main/res/layout/layout_tab_viewpager.xml new file mode 100644 index 0000000..d32546a --- /dev/null +++ b/app/src/main/res/layout/layout_tab_viewpager.xml @@ -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> \ No newline at end of file -- Gitblit v1.9.1