[mobile] redesign home

pull/123/head
FongMi 3 years ago
parent bed33250fb
commit 49114ee5e1
  1. 55
      app/src/mobile/java/com/fongmi/android/tv/ui/activity/MainActivity.java
  2. 11
      app/src/mobile/java/com/fongmi/android/tv/ui/adapter/TypeAdapter.java
  3. 5
      app/src/mobile/java/com/fongmi/android/tv/ui/adapter/VodAdapter.java
  4. 1
      app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java
  5. 103
      app/src/mobile/java/com/fongmi/android/tv/ui/fragment/VodFragment.java
  6. 2
      app/src/mobile/java/com/fongmi/android/tv/ui/fragment/child/ChildFragment.java
  7. 91
      app/src/mobile/java/com/fongmi/android/tv/ui/fragment/child/SiteFragment.java
  8. 8
      app/src/mobile/res/layout/adapter_vod.xml
  9. 10
      app/src/mobile/res/layout/fragment_site.xml
  10. 12
      app/src/mobile/res/layout/fragment_vod.xml
  11. 5
      app/src/mobile/res/menu/menu_nav.xml
  12. 2
      app/src/mobile/res/values-zh-rCN/strings.xml
  13. 2
      app/src/mobile/res/values-zh-rTW/strings.xml

@ -1,7 +1,5 @@
package com.fongmi.android.tv.ui.activity;
import android.app.Activity;
import android.content.Intent;
import android.view.MenuItem;
import androidx.annotation.NonNull;
@ -9,10 +7,15 @@ import androidx.fragment.app.Fragment;
import androidx.viewbinding.ViewBinding;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.api.LiveConfig;
import com.fongmi.android.tv.api.WallConfig;
import com.fongmi.android.tv.databinding.ActivityMainBinding;
import com.fongmi.android.tv.ui.fragment.HomeFragment;
import com.fongmi.android.tv.event.RefreshEvent;
import com.fongmi.android.tv.net.Callback;
import com.fongmi.android.tv.ui.fragment.SettingFragment;
import com.fongmi.android.tv.ui.fragment.VodFragment;
import com.fongmi.android.tv.utils.Notify;
import com.google.android.material.navigation.NavigationBarView;
import java.util.ArrayList;
@ -23,11 +26,6 @@ public class MainActivity extends BaseActivity implements NavigationBarView.OnIt
private ActivityMainBinding mBinding;
private List<Fragment> mFragments;
public static void start(Activity activity) {
activity.startActivity(new Intent(activity, MainActivity.class));
activity.finish();
}
@Override
protected ViewBinding getBinding() {
return mBinding = ActivityMainBinding.inflate(getLayoutInflater());
@ -35,30 +33,51 @@ public class MainActivity extends BaseActivity implements NavigationBarView.OnIt
@Override
protected void initView() {
initFragment();
initConfig();
}
@Override
protected void initEvent() {
mBinding.navigation.setOnItemSelectedListener(this);
mBinding.navigation.setSelectedItemId(R.id.vod);
}
private void initFragment() {
mFragments = new ArrayList<>();
mFragments.add(HomeFragment.newInstance());
mFragments.add(VodFragment.newInstance());
mFragments.add(SettingFragment.newInstance());
for (Fragment fragment : mFragments) getSupportFragmentManager().beginTransaction().add(R.id.container, fragment).hide(fragment).commit();
}
@Override
protected void initEvent() {
mBinding.navigation.setOnItemSelectedListener(this);
mBinding.navigation.setSelectedItemId(R.id.home);
private void initConfig() {
WallConfig.get().init();
LiveConfig.get().init();
ApiConfig.get().init().load(getCallback());
}
private Callback getCallback() {
return new Callback() {
@Override
public void success() {
RefreshEvent.video();
}
@Override
public void error(int resId) {
Notify.show(resId);
}
};
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.home:
getSupportFragmentManager().beginTransaction().show(mFragments.get(0)).hide(mFragments.get(1)).hide(mFragments.get(2)).commit();
return true;
case R.id.vod:
getSupportFragmentManager().beginTransaction().show(mFragments.get(1)).hide(mFragments.get(0)).hide(mFragments.get(2)).commit();
getSupportFragmentManager().beginTransaction().show(mFragments.get(0)).hide(mFragments.get(1)).commit();
return true;
case R.id.setting:
getSupportFragmentManager().beginTransaction().show(mFragments.get(2)).hide(mFragments.get(0)).hide(mFragments.get(1)).commit();
getSupportFragmentManager().beginTransaction().show(mFragments.get(1)).hide(mFragments.get(0)).commit();
return true;
default:
return false;

@ -41,11 +41,18 @@ public class TypeAdapter extends RecyclerView.Adapter<TypeAdapter.ViewHolder> {
}
}
private Class home() {
Class type = new Class();
type.setTypeName("首頁");
type.setTypeId("home");
type.setActivated(true);
return type;
}
public void addAll(List<Class> items) {
if (items.isEmpty()) return;
mItems.clear();
mItems.add(home());
mItems.addAll(items);
mItems.get(0).setActivated(true);
notifyDataSetChanged();
}

@ -55,11 +55,6 @@ public class VodAdapter extends RecyclerView.Adapter<VodAdapter.ViewHolder> {
notifyItemRangeInserted(mItems.size(), items.size());
}
public void clear() {
mItems.clear();
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return mItems.size();

@ -134,7 +134,6 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit
case 0:
Notify.dismiss();
RefreshEvent.video();
RefreshEvent.history();
mBinding.liveUrl.setText(LiveConfig.getUrl());
mBinding.wallUrl.setText(WallConfig.getUrl());
break;

@ -1,6 +1,7 @@
package com.fongmi.android.tv.ui.fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
@ -8,15 +9,25 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.lifecycle.ViewModelProvider;
import androidx.viewbinding.ViewBinding;
import androidx.viewpager.widget.ViewPager;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.bean.Class;
import com.fongmi.android.tv.bean.Result;
import com.fongmi.android.tv.bean.Site;
import com.fongmi.android.tv.databinding.FragmentVodBinding;
import com.fongmi.android.tv.event.RefreshEvent;
import com.fongmi.android.tv.impl.SiteCallback;
import com.fongmi.android.tv.model.SiteViewModel;
import com.fongmi.android.tv.ui.activity.BaseFragment;
import com.fongmi.android.tv.ui.adapter.TypeAdapter;
import com.fongmi.android.tv.ui.custom.dialog.SiteDialog;
import com.fongmi.android.tv.ui.fragment.child.ChildFragment;
import com.fongmi.android.tv.ui.fragment.child.SiteFragment;
import com.fongmi.android.tv.utils.ResUtil;
import com.google.gson.Gson;
import org.greenrobot.eventbus.Subscribe;
@ -25,16 +36,21 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.List;
public class VodFragment extends BaseFragment {
public class VodFragment extends BaseFragment implements SiteCallback {
private FragmentVodBinding mBinding;
private TypeAdapter mAdapter;
private Result mResult;
private SiteViewModel mViewModel;
private TypeAdapter mTypeAdapter;
private PageAdapter mPageAdapter;
public static VodFragment newInstance() {
return new VodFragment();
}
private Site getSite() {
return ApiConfig.get().getHome();
}
@Override
protected ViewBinding getBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) {
return mBinding = FragmentVodBinding.inflate(inflater, container, false);
@ -42,63 +58,104 @@ public class VodFragment extends BaseFragment {
@Override
protected void initView() {
mBinding.recycler.setHasFixedSize(true);
mBinding.recycler.setAdapter(mAdapter = new TypeAdapter());
mBinding.pager.setAdapter(new PageAdapter(getChildFragmentManager()));
setRecyclerView();
setViewModel();
}
@Override
protected void initEvent() {
mAdapter.setListener(item -> mBinding.pager.setCurrentItem(mAdapter.setActivated(item)));
mBinding.title.setOnClickListener(this::onTitle);
mTypeAdapter.setListener(item -> mBinding.pager.setCurrentItem(mTypeAdapter.setActivated(item)));
mBinding.pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
mBinding.recycler.smoothScrollToPosition(position);
mAdapter.setActivated(position);
mTypeAdapter.setActivated(position);
}
});
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onResult(Result result) {
setAdapter(mResult = result);
private void setRecyclerView() {
mBinding.recycler.setHasFixedSize(true);
mBinding.recycler.setItemAnimator(null);
mBinding.recycler.setAdapter(mTypeAdapter = new TypeAdapter());
mBinding.pager.setAdapter(mPageAdapter = new PageAdapter(getChildFragmentManager()));
}
private void setAdapter(Result result) {
result.setTypes(getTypes());
mAdapter.addAll(result.getTypes());
Boolean filter = ApiConfig.get().getHome().isFilterable() ? false : null;
for (Class item : mAdapter.getTypes()) if (result.getFilters().containsKey(item.getTypeId())) item.setFilter(filter);
mBinding.pager.getAdapter().notifyDataSetChanged();
private void setViewModel() {
mViewModel = new ViewModelProvider(this).get(SiteViewModel.class);
mViewModel.result.observe(getViewLifecycleOwner(), result -> {
mPageAdapter.setResult(result);
setAdapter(result);
});
}
private List<Class> getTypes() {
private List<Class> getTypes(Result result) {
List<Class> types = new ArrayList<>();
for (String cate : ApiConfig.get().getHome().getCategories()) for (Class item : mResult.getTypes()) if (cate.equals(item.getTypeName())) types.add(item);
for (String cate : getSite().getCategories()) for (Class type : result.getTypes()) if (cate.equals(type.getTypeName())) types.add(type);
return types;
}
private void setAdapter(Result result) {
result.setTypes(getTypes(result));
mTypeAdapter.addAll(result.getTypes());
Boolean filter = getSite().isFilterable() ? false : null;
for (Class item : mTypeAdapter.getTypes()) if (result.getFilters().containsKey(item.getTypeId())) item.setFilter(filter);
mPageAdapter.notifyDataSetChanged();
mBinding.pager.setCurrentItem(0);
}
public void onTitle(View view) {
SiteDialog.create(this).filter(true).show();
}
@Override
public void setSite(Site item) {
ApiConfig.get().setHome(item);
homeContent();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onRefreshEvent(RefreshEvent event) {
if (event.getType() == RefreshEvent.Type.VIDEO) homeContent();
}
private void homeContent() {
String home = getSite().getName();
mBinding.title.setText(home.isEmpty() ? ResUtil.getString(R.string.app_name) : home);
if (getSite().getKey().isEmpty()) return;
mViewModel.homeContent();
}
class PageAdapter extends FragmentStatePagerAdapter {
private Result result;
public PageAdapter(@NonNull FragmentManager fm) {
super(fm);
}
public void setResult(Result result) {
this.result = result;
}
@NonNull
@Override
public Fragment getItem(int position) {
Class type = mAdapter.get(position);
String filter = new Gson().toJson(mResult.getFilters().get(type.getTypeId()));
Class type = mTypeAdapter.get(position);
if (position == 0) return SiteFragment.newInstance(result.getList());
String filter = new Gson().toJson(result.getFilters().get(type.getTypeId()));
return ChildFragment.newInstance(type.getTypeId(), filter, type.getTypeFlag().equals("1"));
}
@Override
public int getCount() {
return mAdapter.getItemCount();
return mTypeAdapter.getItemCount();
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}
}
}

@ -1,4 +1,4 @@
package com.fongmi.android.tv.ui.fragment;
package com.fongmi.android.tv.ui.fragment.child;
import android.os.Bundle;
import android.view.LayoutInflater;

@ -1,65 +1,57 @@
package com.fongmi.android.tv.ui.fragment;
package com.fongmi.android.tv.ui.fragment.child;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.viewbinding.ViewBinding;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.api.LiveConfig;
import com.fongmi.android.tv.api.WallConfig;
import com.fongmi.android.tv.bean.History;
import com.fongmi.android.tv.bean.Result;
import com.fongmi.android.tv.bean.Vod;
import com.fongmi.android.tv.databinding.FragmentHomeBinding;
import com.fongmi.android.tv.databinding.FragmentSiteBinding;
import com.fongmi.android.tv.event.RefreshEvent;
import com.fongmi.android.tv.model.SiteViewModel;
import com.fongmi.android.tv.net.Callback;
import com.fongmi.android.tv.ui.activity.BaseFragment;
import com.fongmi.android.tv.ui.adapter.HistoryAdapter;
import com.fongmi.android.tv.ui.adapter.VodAdapter;
import com.fongmi.android.tv.ui.custom.SpaceItemDecoration;
import com.fongmi.android.tv.utils.Notify;
import com.fongmi.android.tv.utils.ResUtil;
import com.google.gson.Gson;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
public class HomeFragment extends BaseFragment implements VodAdapter.OnClickListener, HistoryAdapter.OnClickListener {
import java.util.List;
private FragmentHomeBinding mBinding;
public class SiteFragment extends BaseFragment implements VodAdapter.OnClickListener, HistoryAdapter.OnClickListener {
private FragmentSiteBinding mBinding;
private HistoryAdapter mHistoryAdapter;
private SiteViewModel mViewModel;
private VodAdapter mVodAdapter;
private Result result;
public static HomeFragment newInstance() {
return new HomeFragment();
private String getList() {
return getArguments().getString("list");
}
public static SiteFragment newInstance(List<Vod> list) {
Bundle args = new Bundle();
args.putString("list", new Gson().toJson(list));
SiteFragment fragment = new SiteFragment();
fragment.setArguments(args);
return fragment;
}
@Override
protected ViewBinding getBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) {
return mBinding = FragmentHomeBinding.inflate(inflater, container, false);
return mBinding = FragmentSiteBinding.inflate(inflater, container, false);
}
@Override
protected void initView() {
WallConfig.get().init();
LiveConfig.get().init();
ApiConfig.get().init().load(getCallback());
mBinding.progressLayout.showProgress();
setRecyclerView();
setViewModel();
}
@Override
protected void initEvent() {
getHistory();
getVideo();
}
private void setRecyclerView() {
@ -73,43 +65,12 @@ public class HomeFragment extends BaseFragment implements VodAdapter.OnClickList
mBinding.recommend.setAdapter(mVodAdapter = new VodAdapter(this));
}
private void setViewModel() {
mViewModel = new ViewModelProvider(this).get(SiteViewModel.class);
mViewModel.result.observe(getViewLifecycleOwner(), result -> {
mBinding.progressLayout.showContent();
mVodAdapter.addAll(result.getList());
this.result = result;
});
}
private Callback getCallback() {
return new Callback() {
@Override
public void success() {
getHistory();
getVideo();
}
@Override
public void error(int resId) {
mBinding.progressLayout.showContent();
Notify.show(resId);
}
};
private void getHistory() {
mHistoryAdapter.addAll(History.get());
}
private void getVideo() {
mVodAdapter.clear();
result = Result.empty();
String home = ApiConfig.get().getHome().getName();
mBinding.title.setText(home.isEmpty() ? ResUtil.getString(R.string.app_name) : home);
if (ApiConfig.get().getHome().getKey().isEmpty()) return;
mBinding.progressLayout.showProgress();
mViewModel.homeContent();
}
private void getHistory() {
mHistoryAdapter.addAll(History.get());
mVodAdapter.addAll(Vod.arrayFrom(getList()));
}
@Override
@ -134,8 +95,8 @@ public class HomeFragment extends BaseFragment implements VodAdapter.OnClickList
@Subscribe(threadMode = ThreadMode.MAIN)
public void onRefreshEvent(RefreshEvent event) {
switch (event.getType()) {
case VIDEO:
getVideo();
case IMAGE:
mVodAdapter.notifyItemRangeChanged(0, mVodAdapter.getItemCount());
break;
case HISTORY:
getHistory();

@ -36,7 +36,7 @@
android:padding="4dp"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="14sp"
android:textSize="12sp"
android:visibility="gone"
tools:text="2022"
tools:visibility="visible" />
@ -51,7 +51,7 @@
android:padding="4dp"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="14sp"
android:textSize="12sp"
android:visibility="gone"
tools:text="泥巴"
tools:visibility="visible" />
@ -66,7 +66,7 @@
android:padding="4dp"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="14sp"
android:textSize="12sp"
tools:text="1080p" />
<TextView
@ -80,7 +80,7 @@
android:padding="6dp"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="16sp"
android:textSize="14sp"
tools:text="蜘蛛人" />
</RelativeLayout>

@ -11,18 +11,8 @@
android:padding="16dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/home_history"
android:textColor="@color/white"
android:textSize="18sp" />

@ -12,6 +12,18 @@
android:elevation="0dp"
app:elevation="0dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"
app:layout_scrollFlags="scroll|enterAlways" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"

@ -1,11 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/home"
android:icon="@drawable/ic_home"
android:title="@string/nav_home" />
<item
android:id="@+id/vod"
android:icon="@drawable/ic_vod"

@ -2,7 +2,7 @@
<!-- Nav -->
<string name="nav_home">首页</string>
<string name="nav_vod">片库</string>
<string name="nav_vod">点播</string>
<string name="nav_setting">设定</string>
<!-- Home -->

@ -2,7 +2,7 @@
<!-- Nav -->
<string name="nav_home">首頁</string>
<string name="nav_vod">片庫</string>
<string name="nav_vod">點播</string>
<string name="nav_setting">設定</string>
<!-- Home -->

Loading…
Cancel
Save