Two-tabs layout: non-cache and cache modules

This commit is contained in:
dvdandroid 2016-08-21 16:42:50 +02:00 committed by topjohnwu
parent 31b552ab51
commit 5279226f36
6 changed files with 194 additions and 73 deletions

View File

@ -113,6 +113,8 @@ public class WelcomeActivity extends AppCompatActivity implements NavigationView
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.fade_in, R.anim.fade_out); transaction.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
try { try {
toolbar.setElevation(navFragment instanceof ModulesFragment ? 0 : 10);
transaction.replace(R.id.content_frame, navFragment).commit(); transaction.replace(R.id.content_frame, navFragment).commit();
} catch (IllegalStateException ignored) { } catch (IllegalStateException ignored) {
} }

View File

@ -9,7 +9,6 @@ import java.io.FileReader;
public class Module { public class Module {
private final boolean isValid; private final boolean isValid;
private final boolean isCache;
private File mRemoveFile; private File mRemoveFile;
private File mDisableFile; private File mDisableFile;
@ -21,7 +20,6 @@ public class Module {
private String mDescription; private String mDescription;
public Module(File file) { public Module(File file) {
this.isCache = file.getPath().contains("cache");
this.isValid = new File(file + "/module.prop").exists(); this.isValid = new File(file + "/module.prop").exists();
if (!isValid) return; if (!isValid) return;
@ -35,10 +33,6 @@ public class Module {
return isValid && mPropFile != null; return isValid && mPropFile != null;
} }
public boolean isCache() {
return isCache;
}
public String getName() { public String getName() {
return mName; return mName;
} }

View File

@ -0,0 +1,84 @@
package com.topjohnwu.magisk.ui;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.model.Module;
import com.topjohnwu.magisk.rv.ItemClickListener;
import com.topjohnwu.magisk.rv.ModulesAdapter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
public abstract class BaseModuleFragment extends Fragment {
@BindView(R.id.recyclerView) RecyclerView recyclerView;
private ItemClickListener moduleActions = new ItemClickListener() {
@Override
public void onItemClick(final View view, final int position) {
PopupMenu popup = new PopupMenu(getContext(), view);
// Force show icons
try {
Field[] fields = popup.getClass().getDeclaredFields();
for (Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(popup);
Class<?> classPopupHelper = Class.forName(menuPopupHelper.getClass().getName());
Method setForceIcons = classPopupHelper.getMethod("setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Exception ignored) {
}
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.remove:
listModules().get(position).createRemoveFile();
Snackbar.make(view, R.string.remove_file_created, Snackbar.LENGTH_SHORT).show();
break;
case R.id.disable:
listModules().get(position).createDisableFile();
Snackbar.make(view, R.string.disable_file_created, Snackbar.LENGTH_SHORT).show();
break;
}
return false;
}
});
popup.inflate(R.menu.module_popup);
popup.show();
}
};
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.single_module_fragment, container, false);
ButterKnife.bind(this, view);
recyclerView.setAdapter(new ModulesAdapter(listModules(), moduleActions));
return view;
}
protected abstract List<Module> listModules();
}

View File

@ -3,25 +3,22 @@ package com.topjohnwu.magisk.ui;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar; import android.support.design.widget.TabLayout;
import android.support.v7.widget.PopupMenu; import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.model.Module; import com.topjohnwu.magisk.model.Module;
import com.topjohnwu.magisk.rv.ItemClickListener;
import com.topjohnwu.magisk.rv.ModulesAdapter;
import com.topjohnwu.magisk.ui.utils.Utils; import com.topjohnwu.magisk.ui.utils.Utils;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -33,63 +30,53 @@ public class ModulesFragment extends android.support.v4.app.Fragment {
private static final String MAGISK_PATH = "/magisk"; private static final String MAGISK_PATH = "/magisk";
private static final String MAGISK_CACHE_PATH = "/cache/magisk"; private static final String MAGISK_CACHE_PATH = "/cache/magisk";
@BindView(R.id.recyclerView) RecyclerView recyclerView; private static List<Module> listModulesNoCache = new ArrayList<>();
private static List<Module> listModulesCache = new ArrayList<>();
@BindView(R.id.progressBar) ProgressBar progressBar; @BindView(R.id.progressBar) ProgressBar progressBar;
@BindView(R.id.pager) ViewPager viewPager;
@BindView(R.id.tab_layout) TabLayout tabLayout;
private List<Module> listModules = new ArrayList<>();
private ItemClickListener moduleActions = new ItemClickListener() {
@Override @Override
public void onItemClick(final View view, final int position) { public void onCreate(@Nullable Bundle savedInstanceState) {
PopupMenu popup = new PopupMenu(getContext(), view); super.onCreate(savedInstanceState);
try {
Field[] fields = popup.getClass().getDeclaredFields();
for (Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(popup);
Class<?> classPopupHelper = Class.forName(menuPopupHelper.getClass().getName());
Method setForceIcons = classPopupHelper.getMethod("setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Exception ignored) {
}
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { listModulesCache.clear();
@Override listModulesNoCache.clear();
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.remove:
listModules.get(position).createRemoveFile();
Snackbar.make(view, R.string.remove_file_created, Snackbar.LENGTH_SHORT).show();
break;
case R.id.disable:
listModules.get(position).createDisableFile();
Snackbar.make(view, R.string.disable_file_created, Snackbar.LENGTH_SHORT).show();
break;
} }
return false;
}
});
popup.inflate(R.menu.module_popup);
popup.show();
}
};
@Nullable @Nullable
@Override @Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.modules_fragment, container, false); View view = inflater.inflate(R.layout.modules_fragment, container, false);
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
viewPager.setAdapter(new TabsAdapter(getChildFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
new CheckFolders().execute(); new CheckFolders().execute();
return view; return view;
} }
public static class NoCacheModuleFragment extends BaseModuleFragment {
@Override
protected List<Module> listModules() {
return listModulesNoCache;
}
}
public static class CacheModuleFragment extends BaseModuleFragment {
@Override
protected List<Module> listModules() {
return listModulesCache;
}
}
private class CheckFolders extends AsyncTask<Void, Integer, Boolean> { private class CheckFolders extends AsyncTask<Void, Integer, Boolean> {
@Override @Override
@ -114,7 +101,11 @@ public class ModulesFragment extends android.support.v4.app.Fragment {
for (File mod : magisk) { for (File mod : magisk) {
Module m = new Module(mod); Module m = new Module(mod);
if (m.isValid()) { if (m.isValid()) {
listModules.add(m); try {
m.parse();
listModulesNoCache.add(m);
} catch (Exception ignored) {
}
} }
} }
} }
@ -123,18 +114,14 @@ public class ModulesFragment extends android.support.v4.app.Fragment {
for (File mod : magiskCache) { for (File mod : magiskCache) {
Module m = new Module(mod); Module m = new Module(mod);
if (m.isValid()) { if (m.isValid()) {
listModules.add(m);
}
}
}
//noinspection Convert2streamapi
for (Module module : listModules) {
try { try {
module.parse(); m.parse();
listModulesCache.add(m);
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }
}
}
return true; return true;
} }
@ -144,9 +131,37 @@ public class ModulesFragment extends android.support.v4.app.Fragment {
super.onPostExecute(result); super.onPostExecute(result);
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
recyclerView.setAdapter(new ModulesAdapter(listModules, moduleActions));
} }
} }
private class TabsAdapter extends FragmentPagerAdapter {
String[] tabTitles = new String[]{
"_no_cache", "_cache"
// TODO stringify
};
public TabsAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return tabTitles.length;
}
@Override
public String getPageTitle(int position) {
return tabTitles[position];
}
@Override
public Fragment getItem(int position) {
if (position == 0) {
return new NoCacheModuleFragment();
} else {
return new CacheModuleFragment();
}
}
}
} }

View File

@ -6,16 +6,28 @@
android:layout_marginTop="?attr/actionBarSize" android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical"> android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:minHeight="?attr/actionBarSize"
app:tabGravity="fill"
app:tabIndicatorColor="?attr/colorAccent"
app:tabMode="fixed"
app:tabTextAppearance="@style/TextAppearance.Design.Tab"/>
<ProgressBar <ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/progressBar"
android:layout_gravity="center"/> android:layout_gravity="center"/>
<android.support.v7.widget.RecyclerView <android.support.v4.view.ViewPager
android:id="@+id/recyclerView" android:id="@+id/pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dp"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"/> android:layout_weight="1"/>
</LinearLayout> </LinearLayout>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"/>
</LinearLayout>