mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-30 21:45:27 +00:00
Update repo fragment and adapter
This commit is contained in:
parent
6933bcf7bb
commit
10efe3859d
@ -3,7 +3,6 @@ package com.topjohnwu.magisk;
|
|||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -136,7 +135,7 @@ public class MagiskFragment extends Fragment
|
|||||||
private boolean verity = keepVerityChkbox.isChecked();
|
private boolean verity = keepVerityChkbox.isChecked();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadDone(Uri uri, Context context) {
|
public void onDownloadDone(Uri uri) {
|
||||||
if (Shell.rootAccess()) {
|
if (Shell.rootAccess()) {
|
||||||
magiskManager.shell.su_raw(
|
magiskManager.shell.su_raw(
|
||||||
"rm -f /dev/.magisk",
|
"rm -f /dev/.magisk",
|
||||||
@ -144,7 +143,7 @@ public class MagiskFragment extends Fragment
|
|||||||
"echo \"KEEPFORCEENCRYPT=" + String.valueOf(enc) + "\" >> /dev/.magisk",
|
"echo \"KEEPFORCEENCRYPT=" + String.valueOf(enc) + "\" >> /dev/.magisk",
|
||||||
"echo \"KEEPVERITY=" + String.valueOf(verity) + "\" >> /dev/.magisk"
|
"echo \"KEEPVERITY=" + String.valueOf(verity) + "\" >> /dev/.magisk"
|
||||||
);
|
);
|
||||||
startActivity(new Intent(context, FlashActivity.class).setData(uri));
|
startActivity(new Intent(getActivity(), FlashActivity.class).setData(uri));
|
||||||
} else {
|
} else {
|
||||||
Utils.showUriSnack(getActivity(), uri);
|
Utils.showUriSnack(getActivity(), uri);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package com.topjohnwu.magisk;
|
|||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.view.MenuItemCompat;
|
|
||||||
import android.support.v4.widget.SwipeRefreshLayout;
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@ -14,18 +13,11 @@ import android.widget.SearchView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.adapters.ReposAdapter;
|
import com.topjohnwu.magisk.adapters.ReposAdapter;
|
||||||
import com.topjohnwu.magisk.adapters.SimpleSectionedRecyclerViewAdapter;
|
|
||||||
import com.topjohnwu.magisk.asyncs.LoadRepos;
|
import com.topjohnwu.magisk.asyncs.LoadRepos;
|
||||||
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
|
||||||
import com.topjohnwu.magisk.components.Fragment;
|
import com.topjohnwu.magisk.components.Fragment;
|
||||||
import com.topjohnwu.magisk.module.Module;
|
|
||||||
import com.topjohnwu.magisk.module.Repo;
|
|
||||||
import com.topjohnwu.magisk.utils.CallbackEvent;
|
import com.topjohnwu.magisk.utils.CallbackEvent;
|
||||||
import com.topjohnwu.magisk.utils.Logger;
|
import com.topjohnwu.magisk.utils.Logger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.Unbinder;
|
import butterknife.Unbinder;
|
||||||
@ -37,16 +29,7 @@ public class ReposFragment extends Fragment implements CallbackEvent.Listener<Vo
|
|||||||
@BindView(R.id.empty_rv) TextView emptyRv;
|
@BindView(R.id.empty_rv) TextView emptyRv;
|
||||||
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
|
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
|
||||||
|
|
||||||
private List<Repo> mUpdateRepos = new ArrayList<>();
|
private ReposAdapter adapter;
|
||||||
private List<Repo> mInstalledRepos = new ArrayList<>();
|
|
||||||
private List<Repo> mOthersRepos = new ArrayList<>();
|
|
||||||
private List<Repo> fUpdateRepos = new ArrayList<>();
|
|
||||||
private List<Repo> fInstalledRepos = new ArrayList<>();
|
|
||||||
private List<Repo> fOthersRepos = new ArrayList<>();
|
|
||||||
|
|
||||||
private SimpleSectionedRecyclerViewAdapter mSectionedAdapter;
|
|
||||||
|
|
||||||
private SearchView.OnQueryTextListener searchListener;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
@ -60,10 +43,9 @@ public class ReposFragment extends Fragment implements CallbackEvent.Listener<Vo
|
|||||||
View view = inflater.inflate(R.layout.fragment_repos, container, false);
|
View view = inflater.inflate(R.layout.fragment_repos, container, false);
|
||||||
unbinder = ButterKnife.bind(this, view);
|
unbinder = ButterKnife.bind(this, view);
|
||||||
|
|
||||||
mSectionedAdapter = new SimpleSectionedRecyclerViewAdapter(R.layout.section,
|
adapter = new ReposAdapter(getApplication().repoMap);
|
||||||
R.id.section_text, new ReposAdapter(fUpdateRepos, fInstalledRepos, fOthersRepos));
|
|
||||||
|
|
||||||
recyclerView.setAdapter(mSectionedAdapter);
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
mSwipeRefreshLayout.setRefreshing(true);
|
mSwipeRefreshLayout.setRefreshing(true);
|
||||||
|
|
||||||
@ -73,38 +55,42 @@ public class ReposFragment extends Fragment implements CallbackEvent.Listener<Vo
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (getApplication().repoLoadDone.isTriggered) {
|
if (getApplication().repoLoadDone.isTriggered) {
|
||||||
reloadRepos();
|
onTrigger(null);
|
||||||
updateUI();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
searchListener = new SearchView.OnQueryTextListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onQueryTextSubmit(String query) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onQueryTextChange(String newText) {
|
|
||||||
new FilterApps().exec(newText);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTrigger(CallbackEvent<Void> event) {
|
public void onTrigger(CallbackEvent<Void> event) {
|
||||||
Logger.dev("ReposFragment: UI refresh triggered");
|
Logger.dev("ReposFragment: UI refresh triggered");
|
||||||
reloadRepos();
|
if (getApplication().repoMap.isEmpty()) {
|
||||||
updateUI();
|
recyclerView.setVisibility(View.GONE);
|
||||||
|
emptyRv.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
adapter.filter(getApplication().moduleMap, "");
|
||||||
|
recyclerView.setVisibility(View.VISIBLE);
|
||||||
|
emptyRv.setVisibility(View.GONE);
|
||||||
|
mSwipeRefreshLayout.setRefreshing(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
inflater.inflate(R.menu.menu_repo, menu);
|
inflater.inflate(R.menu.menu_repo, menu);
|
||||||
SearchView search = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.repo_search));
|
SearchView search = (SearchView) menu.findItem(R.id.repo_search).getActionView();
|
||||||
search.setOnQueryTextListener(searchListener);
|
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onQueryTextSubmit(String query) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onQueryTextChange(String newText) {
|
||||||
|
adapter.filter(getApplication().moduleMap, newText);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -125,92 +111,4 @@ public class ReposFragment extends Fragment implements CallbackEvent.Listener<Vo
|
|||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
unbinder.unbind();
|
unbinder.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reloadRepos() {
|
|
||||||
mUpdateRepos.clear();
|
|
||||||
mInstalledRepos.clear();
|
|
||||||
mOthersRepos.clear();
|
|
||||||
for (Repo repo : getApplication().repoMap.values()) {
|
|
||||||
Module module = getApplication().moduleMap.get(repo.getId());
|
|
||||||
if (module != null) {
|
|
||||||
if (repo.getVersionCode() > module.getVersionCode()) {
|
|
||||||
mUpdateRepos.add(repo);
|
|
||||||
} else {
|
|
||||||
mInstalledRepos.add(repo);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mOthersRepos.add(repo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fUpdateRepos.clear();
|
|
||||||
fInstalledRepos.clear();
|
|
||||||
fOthersRepos.clear();
|
|
||||||
fUpdateRepos.addAll(mUpdateRepos);
|
|
||||||
fInstalledRepos.addAll(mInstalledRepos);
|
|
||||||
fOthersRepos.addAll(mOthersRepos);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateUI() {
|
|
||||||
if (fUpdateRepos.size() + fInstalledRepos.size() + fOthersRepos.size() == 0) {
|
|
||||||
emptyRv.setVisibility(View.VISIBLE);
|
|
||||||
recyclerView.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
List<SimpleSectionedRecyclerViewAdapter.Section> sections = new ArrayList<>();
|
|
||||||
if (!fUpdateRepos.isEmpty()) {
|
|
||||||
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(0, getString(R.string.update_available)));
|
|
||||||
}
|
|
||||||
if (!fInstalledRepos.isEmpty()) {
|
|
||||||
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(fUpdateRepos.size(), getString(R.string.installed)));
|
|
||||||
}
|
|
||||||
if (!fOthersRepos.isEmpty()) {
|
|
||||||
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(fUpdateRepos.size() + fInstalledRepos.size(), getString(R.string.not_installed)));
|
|
||||||
}
|
|
||||||
SimpleSectionedRecyclerViewAdapter.Section[] array = sections.toArray(new SimpleSectionedRecyclerViewAdapter.Section[sections.size()]);
|
|
||||||
mSectionedAdapter.setSections(array);
|
|
||||||
emptyRv.setVisibility(View.GONE);
|
|
||||||
recyclerView.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
mSwipeRefreshLayout.setRefreshing(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class FilterApps extends ParallelTask<String, Void, Void> {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(String... strings) {
|
|
||||||
String newText = strings[0];
|
|
||||||
fUpdateRepos.clear();
|
|
||||||
fInstalledRepos.clear();
|
|
||||||
fOthersRepos.clear();
|
|
||||||
for (Repo repo: mUpdateRepos) {
|
|
||||||
if (repo.getName().toLowerCase().contains(newText.toLowerCase())
|
|
||||||
|| repo.getAuthor().toLowerCase().contains(newText.toLowerCase())
|
|
||||||
|| repo.getDescription().toLowerCase().contains(newText.toLowerCase())
|
|
||||||
) {
|
|
||||||
fUpdateRepos.add(repo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Repo repo: mInstalledRepos) {
|
|
||||||
if (repo.getName().toLowerCase().contains(newText.toLowerCase())
|
|
||||||
|| repo.getAuthor().toLowerCase().contains(newText.toLowerCase())
|
|
||||||
|| repo.getDescription().toLowerCase().contains(newText.toLowerCase())
|
|
||||||
) {
|
|
||||||
fInstalledRepos.add(repo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Repo repo: mOthersRepos) {
|
|
||||||
if (repo.getName().toLowerCase().contains(newText.toLowerCase())
|
|
||||||
|| repo.getAuthor().toLowerCase().contains(newText.toLowerCase())
|
|
||||||
|| repo.getDescription().toLowerCase().contains(newText.toLowerCase())
|
|
||||||
) {
|
|
||||||
fOthersRepos.add(repo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Void v) {
|
|
||||||
updateUI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,67 +16,102 @@ import com.topjohnwu.magisk.R;
|
|||||||
import com.topjohnwu.magisk.asyncs.ProcessRepoZip;
|
import com.topjohnwu.magisk.asyncs.ProcessRepoZip;
|
||||||
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
||||||
import com.topjohnwu.magisk.components.MarkDownWindow;
|
import com.topjohnwu.magisk.components.MarkDownWindow;
|
||||||
|
import com.topjohnwu.magisk.module.Module;
|
||||||
import com.topjohnwu.magisk.module.Repo;
|
import com.topjohnwu.magisk.module.Repo;
|
||||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.magisk.utils.ValueSortedMap;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
|
||||||
public class ReposAdapter extends RecyclerView.Adapter<ReposAdapter.ViewHolder> {
|
public class ReposAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
|
|
||||||
|
private static final int SECTION_TYPE = 0;
|
||||||
|
private static final int REPO_TYPE = 1;
|
||||||
|
|
||||||
private List<Repo> mUpdateRepos, mInstalledRepos, mOthersRepos;
|
private List<Repo> mUpdateRepos, mInstalledRepos, mOthersRepos;
|
||||||
private Context mContext;
|
private int[] sectionList;
|
||||||
|
private int size;
|
||||||
|
private ValueSortedMap<String, Repo> repoMap;
|
||||||
|
|
||||||
public ReposAdapter(List<Repo> update, List<Repo> installed, List<Repo> others) {
|
public ReposAdapter(ValueSortedMap<String, Repo> map) {
|
||||||
mUpdateRepos = update;
|
repoMap = map;
|
||||||
mInstalledRepos = installed;
|
mUpdateRepos = new ArrayList<>();
|
||||||
mOthersRepos = others;
|
mInstalledRepos = new ArrayList<>();
|
||||||
|
mOthersRepos = new ArrayList<>();
|
||||||
|
sectionList = new int[3];
|
||||||
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
mContext = parent.getContext();
|
Context context = parent.getContext();
|
||||||
View v = LayoutInflater.from(mContext).inflate(R.layout.list_item_repo, parent, false);
|
View v;
|
||||||
return new ViewHolder(v);
|
RecyclerView.ViewHolder holder = null;
|
||||||
|
switch (viewType) {
|
||||||
|
case SECTION_TYPE:
|
||||||
|
v = LayoutInflater.from(context).inflate(R.layout.section, parent, false);
|
||||||
|
holder = new SectionHolder(v);
|
||||||
|
break;
|
||||||
|
case REPO_TYPE:
|
||||||
|
v = LayoutInflater.from(context).inflate(R.layout.list_item_repo, parent, false);
|
||||||
|
holder = new RepoHolder(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(final ViewHolder holder, int position) {
|
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
||||||
Repo repo = getItem(position);
|
Context context = holder.itemView.getContext();
|
||||||
|
switch (getItemViewType(position)) {
|
||||||
holder.title.setText(repo.getName());
|
case SECTION_TYPE:
|
||||||
holder.versionName.setText(repo.getVersion());
|
SectionHolder section = (SectionHolder) holder;
|
||||||
|
if (position == sectionList[0]) {
|
||||||
|
section.sectionText.setText(context.getString(R.string.update_available));
|
||||||
|
} else if (position == sectionList[1]) {
|
||||||
|
section.sectionText.setText(context.getString(R.string.installed));
|
||||||
|
} else {
|
||||||
|
section.sectionText.setText(context.getString(R.string.not_installed));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REPO_TYPE:
|
||||||
|
RepoHolder repoHolder = (RepoHolder) holder;
|
||||||
|
Repo repo = getRepo(position);
|
||||||
|
repoHolder.title.setText(repo.getName());
|
||||||
|
repoHolder.versionName.setText(repo.getVersion());
|
||||||
String author = repo.getAuthor();
|
String author = repo.getAuthor();
|
||||||
holder.author.setText(TextUtils.isEmpty(author) ? null : mContext.getString(R.string.author, author));
|
repoHolder.author.setText(TextUtils.isEmpty(author) ? null : context.getString(R.string.author, author));
|
||||||
holder.description.setText(repo.getDescription());
|
repoHolder.description.setText(repo.getDescription());
|
||||||
|
|
||||||
holder.infoLayout.setOnClickListener(v -> new MarkDownWindow(null, repo.getDetailUrl(), mContext));
|
repoHolder.infoLayout.setOnClickListener(v -> new MarkDownWindow(null, repo.getDetailUrl(), context));
|
||||||
|
|
||||||
holder.downloadImage.setOnClickListener(v -> {
|
repoHolder.downloadImage.setOnClickListener(v -> {
|
||||||
String filename = repo.getName() + "-" + repo.getVersion() + ".zip";
|
String filename = repo.getName() + "-" + repo.getVersion() + ".zip";
|
||||||
new AlertDialogBuilder(mContext)
|
new AlertDialogBuilder(context)
|
||||||
.setTitle(mContext.getString(R.string.repo_install_title, repo.getName()))
|
.setTitle(context.getString(R.string.repo_install_title, repo.getName()))
|
||||||
.setMessage(mContext.getString(R.string.repo_install_msg, filename))
|
.setMessage(context.getString(R.string.repo_install_msg, filename))
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setPositiveButton(R.string.install, (d, i) -> Utils.dlAndReceive(
|
.setPositiveButton(R.string.install, (d, i) -> Utils.dlAndReceive(
|
||||||
mContext,
|
context,
|
||||||
new DownloadReceiver() {
|
new DownloadReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadDone(Uri uri, Context context) {
|
public void onDownloadDone(Uri uri) {
|
||||||
new ProcessRepoZip((Activity) mContext, uri, true).exec();
|
new ProcessRepoZip((Activity) context, uri, true).exec();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
repo.getZipUrl(),
|
repo.getZipUrl(),
|
||||||
Utils.getLegalFilename(filename)))
|
Utils.getLegalFilename(filename)))
|
||||||
.setNeutralButton(R.string.download, (d, i) -> Utils.dlAndReceive(
|
.setNeutralButton(R.string.download, (d, i) -> Utils.dlAndReceive(
|
||||||
mContext,
|
context,
|
||||||
new DownloadReceiver() {
|
new DownloadReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadDone(Uri uri, Context context) {
|
public void onDownloadDone(Uri uri) {
|
||||||
new ProcessRepoZip((Activity) mContext, uri, false).exec();
|
new ProcessRepoZip((Activity) context, uri, false).exec();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
repo.getZipUrl(),
|
repo.getZipUrl(),
|
||||||
@ -84,28 +119,81 @@ public class ReposAdapter extends RecyclerView.Adapter<ReposAdapter.ViewHolder>
|
|||||||
.setNegativeButton(R.string.no_thanks, null)
|
.setNegativeButton(R.string.no_thanks, null)
|
||||||
.show();
|
.show();
|
||||||
});
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
for (int i : sectionList) {
|
||||||
|
if (position == i)
|
||||||
|
return SECTION_TYPE;
|
||||||
|
}
|
||||||
|
return REPO_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return mUpdateRepos.size() + mInstalledRepos.size() + mOthersRepos.size();
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Repo getItem(int position) {
|
public void filter(ValueSortedMap<String, Module> moduleMap, String s) {
|
||||||
if (position >= mUpdateRepos.size()) {
|
mUpdateRepos.clear();
|
||||||
|
mInstalledRepos.clear();
|
||||||
|
mOthersRepos.clear();
|
||||||
|
sectionList[0] = sectionList[1] = sectionList[2] = 0;
|
||||||
|
for (Repo repo : repoMap.values()) {
|
||||||
|
if (repo.getName().toLowerCase().contains(s.toLowerCase())
|
||||||
|
|| repo.getAuthor().toLowerCase().contains(s.toLowerCase())
|
||||||
|
|| repo.getDescription().toLowerCase().contains(s.toLowerCase())
|
||||||
|
) {
|
||||||
|
// Passed the filter
|
||||||
|
Module module = moduleMap.get(repo.getId());
|
||||||
|
if (module != null) {
|
||||||
|
if (repo.getVersionCode() > module.getVersionCode()) {
|
||||||
|
// Updates
|
||||||
|
mUpdateRepos.add(repo);
|
||||||
|
} else {
|
||||||
|
mInstalledRepos.add(repo);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mOthersRepos.add(repo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sectionList[0] = mUpdateRepos.isEmpty() ? -1 : 0;
|
||||||
|
size = mUpdateRepos.isEmpty() ? 0 : mUpdateRepos.size() + 1;
|
||||||
|
sectionList[1] = mInstalledRepos.isEmpty() ? -1 : size;
|
||||||
|
size += mInstalledRepos.isEmpty() ? 0 : mInstalledRepos.size() + 1;
|
||||||
|
sectionList[2] = mOthersRepos.isEmpty() ? -1 : size;
|
||||||
|
size += mOthersRepos.isEmpty() ? 0 : mOthersRepos.size() + 1;
|
||||||
|
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Repo getRepo(int position) {
|
||||||
|
if (!mUpdateRepos.isEmpty()) position -= 1;
|
||||||
|
if (position < mUpdateRepos.size()) return mUpdateRepos.get(position);
|
||||||
position -= mUpdateRepos.size();
|
position -= mUpdateRepos.size();
|
||||||
if (position >= mInstalledRepos.size()) {
|
if (!mInstalledRepos.isEmpty()) position -= 1;
|
||||||
|
if (position < mInstalledRepos.size()) return mInstalledRepos.get(position);
|
||||||
position -= mInstalledRepos.size();
|
position -= mInstalledRepos.size();
|
||||||
|
if (!mOthersRepos.isEmpty()) position -= 1;
|
||||||
return mOthersRepos.get(position);
|
return mOthersRepos.get(position);
|
||||||
} else {
|
|
||||||
return mInstalledRepos.get(position);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return mUpdateRepos.get(position);
|
static class SectionHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
@BindView(R.id.section_text) TextView sectionText;
|
||||||
|
|
||||||
|
SectionHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
ButterKnife.bind(this, itemView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
static class RepoHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
@BindView(R.id.title) TextView title;
|
@BindView(R.id.title) TextView title;
|
||||||
@BindView(R.id.version_name) TextView versionName;
|
@BindView(R.id.version_name) TextView versionName;
|
||||||
@ -114,7 +202,7 @@ public class ReposAdapter extends RecyclerView.Adapter<ReposAdapter.ViewHolder>
|
|||||||
@BindView(R.id.info_layout) LinearLayout infoLayout;
|
@BindView(R.id.info_layout) LinearLayout infoLayout;
|
||||||
@BindView(R.id.download) ImageView downloadImage;
|
@BindView(R.id.download) ImageView downloadImage;
|
||||||
|
|
||||||
ViewHolder(View itemView) {
|
RepoHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
ButterKnife.bind(this, itemView);
|
ButterKnife.bind(this, itemView);
|
||||||
}
|
}
|
||||||
|
@ -1,178 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.adapters;
|
|
||||||
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.util.SparseArray;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
public class SimpleSectionedRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
|
||||||
|
|
||||||
private static final int SECTION_TYPE = 0;
|
|
||||||
|
|
||||||
private boolean mValid = true;
|
|
||||||
private int mSectionResourceId;
|
|
||||||
private int mTextResourceId;
|
|
||||||
private RecyclerView.Adapter mBaseAdapter;
|
|
||||||
private SparseArray<Section> mSections = new SparseArray<Section>();
|
|
||||||
|
|
||||||
|
|
||||||
public SimpleSectionedRecyclerViewAdapter(int sectionResourceId, int textResourceId,
|
|
||||||
RecyclerView.Adapter baseAdapter) {
|
|
||||||
|
|
||||||
mSectionResourceId = sectionResourceId;
|
|
||||||
mTextResourceId = textResourceId;
|
|
||||||
mBaseAdapter = baseAdapter;
|
|
||||||
|
|
||||||
mBaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
|
||||||
@Override
|
|
||||||
public void onChanged() {
|
|
||||||
mValid = mBaseAdapter.getItemCount()>0;
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemRangeChanged(int positionStart, int itemCount) {
|
|
||||||
mValid = mBaseAdapter.getItemCount()>0;
|
|
||||||
notifyItemRangeChanged(positionStart, itemCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemRangeInserted(int positionStart, int itemCount) {
|
|
||||||
mValid = mBaseAdapter.getItemCount()>0;
|
|
||||||
notifyItemRangeInserted(positionStart, itemCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemRangeRemoved(int positionStart, int itemCount) {
|
|
||||||
mValid = mBaseAdapter.getItemCount()>0;
|
|
||||||
notifyItemRangeRemoved(positionStart, itemCount);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class SectionViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
public TextView title;
|
|
||||||
|
|
||||||
public SectionViewHolder(View view, int mTextResourceid) {
|
|
||||||
super(view);
|
|
||||||
title = (TextView) view.findViewById(mTextResourceid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int typeView) {
|
|
||||||
if (typeView == SECTION_TYPE) {
|
|
||||||
View view = LayoutInflater.from(parent.getContext()).inflate(mSectionResourceId, parent, false);
|
|
||||||
return new SectionViewHolder(view,mTextResourceId);
|
|
||||||
}else{
|
|
||||||
return mBaseAdapter.onCreateViewHolder(parent, typeView -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(RecyclerView.ViewHolder sectionViewHolder, int position) {
|
|
||||||
if (isSectionHeaderPosition(position)) {
|
|
||||||
((SectionViewHolder)sectionViewHolder).title.setText(mSections.get(position).title);
|
|
||||||
}else{
|
|
||||||
mBaseAdapter.onBindViewHolder(sectionViewHolder,sectionedPositionToPosition(position));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemViewType(int position) {
|
|
||||||
return isSectionHeaderPosition(position)
|
|
||||||
? SECTION_TYPE
|
|
||||||
: mBaseAdapter.getItemViewType(sectionedPositionToPosition(position)) +1 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class Section {
|
|
||||||
int firstPosition;
|
|
||||||
int sectionedPosition;
|
|
||||||
CharSequence title;
|
|
||||||
|
|
||||||
public Section(int firstPosition, CharSequence title) {
|
|
||||||
this.firstPosition = firstPosition;
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setSections(Section[] sections) {
|
|
||||||
mSections.clear();
|
|
||||||
|
|
||||||
Arrays.sort(sections, new Comparator<Section>() {
|
|
||||||
@Override
|
|
||||||
public int compare(Section o, Section o1) {
|
|
||||||
return (o.firstPosition == o1.firstPosition)
|
|
||||||
? 0
|
|
||||||
: ((o.firstPosition < o1.firstPosition) ? -1 : 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
int offset = 0; // offset positions for the headers we're adding
|
|
||||||
for (Section section : sections) {
|
|
||||||
section.sectionedPosition = section.firstPosition + offset;
|
|
||||||
mSections.append(section.sectionedPosition, section);
|
|
||||||
++offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int positionToSectionedPosition(int position) {
|
|
||||||
int offset = 0;
|
|
||||||
for (int i = 0; i < mSections.size(); i++) {
|
|
||||||
if (mSections.valueAt(i).firstPosition > position) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++offset;
|
|
||||||
}
|
|
||||||
return position + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int sectionedPositionToPosition(int sectionedPosition) {
|
|
||||||
if (isSectionHeaderPosition(sectionedPosition)) {
|
|
||||||
return RecyclerView.NO_POSITION;
|
|
||||||
}
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
for (int i = 0; i < mSections.size(); i++) {
|
|
||||||
if (mSections.valueAt(i).sectionedPosition > sectionedPosition) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
--offset;
|
|
||||||
}
|
|
||||||
return sectionedPosition + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSectionHeaderPosition(int position) {
|
|
||||||
return mSections.get(position) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int position) {
|
|
||||||
return isSectionHeaderPosition(position)
|
|
||||||
? Integer.MAX_VALUE - mSections.indexOfKey(position)
|
|
||||||
: mBaseAdapter.getItemId(sectionedPositionToPosition(position));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return (mValid ? mBaseAdapter.getItemCount() + mSections.size() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -31,7 +31,7 @@ public abstract class DownloadReceiver extends BroadcastReceiver {
|
|||||||
switch (status) {
|
switch (status) {
|
||||||
case DownloadManager.STATUS_SUCCESSFUL:
|
case DownloadManager.STATUS_SUCCESSFUL:
|
||||||
Uri uri = Uri.parse(c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)));
|
Uri uri = Uri.parse(c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)));
|
||||||
onDownloadDone(uri, context);
|
onDownloadDone(uri);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Toast.makeText(context, R.string.download_file_error, Toast.LENGTH_LONG).show();
|
Toast.makeText(context, R.string.download_file_error, Toast.LENGTH_LONG).show();
|
||||||
@ -52,5 +52,5 @@ public abstract class DownloadReceiver extends BroadcastReceiver {
|
|||||||
mFilename = filename;
|
mFilename = filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void onDownloadDone(Uri uri, Context context);
|
public abstract void onDownloadDone(Uri uri);
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ public class ManagerUpdate extends BroadcastReceiver {
|
|||||||
context,
|
context,
|
||||||
new DownloadReceiver() {
|
new DownloadReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadDone(Uri uri, Context context) {
|
public void onDownloadDone(Uri uri) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
Intent install = new Intent(Intent.ACTION_INSTALL_PACKAGE);
|
Intent install = new Intent(Intent.ACTION_INSTALL_PACKAGE);
|
||||||
install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
@ -7,7 +7,7 @@ buildscript {
|
|||||||
maven { url "https://maven.google.com" }
|
maven { url "https://maven.google.com" }
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.0.0-alpha6'
|
classpath 'com.android.tools.build:gradle:3.0.0-alpha7'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
Loading…
Reference in New Issue
Block a user