/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package tk.wasdennnoch.androidn_ify.settings.misc; import android.app.Activity; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import java.util.List; import de.robv.android.xposed.XposedHelpers; import tk.wasdennnoch.androidn_ify.R; import tk.wasdennnoch.androidn_ify.XposedHook; import tk.wasdennnoch.androidn_ify.utils.ConfigUtils; import tk.wasdennnoch.androidn_ify.utils.ResourceUtils; import static tk.wasdennnoch.androidn_ify.XposedHook.PACKAGE_SETTINGS; public class SettingsDrawerAdapter extends RecyclerView.Adapter<SettingsDrawerAdapter.DrawerViewHolder> { private static final String TAG = "SettingsDrawerAdapter"; private static final int TYPE_SPACER = 0; private static final int TYPE_CATEGORY = 1; private static final int TYPE_TILE = 2; private final ArrayList<Item> mItems = new ArrayList<>(); private final Activity mActivity; private SettingsActivityHelper mHelper; public SettingsDrawerAdapter(Activity activity) { mActivity = activity; } void updateCategories() { new CategoriesUpdater().execute(); } @SuppressWarnings("unchecked") private void updateCategoriesInternal() { ResourceUtils res = ResourceUtils.getInstance(mActivity); List<Object> categories = SettingsActivityHelper.getDashboardCategories(); if (categories == null) return; mItems.clear(); // Spacer. mItems.add(null); Item tile = new Item(); tile.label = res.getString(R.string.home); tile.icon = res.getDrawable(R.drawable.home); mItems.add(tile); for (int i = 0; i < categories.size(); i++) { Item category = new Item(); category.icon = null; Object dashboardCategory = categories.get(i); category.label = (CharSequence) XposedHelpers.callMethod(dashboardCategory, "getTitle", mActivity.getResources()); mItems.add(category); List<Object> tiles = (List<Object>) XposedHelpers.getObjectField(dashboardCategory, "tiles"); for (int j = 0; j < tiles.size(); j++) { tile = new Item(); Object dashboardTile = tiles.get(j); tile.label = (CharSequence) XposedHelpers.callMethod(dashboardTile, "getTitle", mActivity.getResources()); tile.icon = getIcon(dashboardTile); tile.tile = dashboardTile; mItems.add(tile); } } } private Drawable getIcon(Object dashboardTile) { int iconRes = XposedHelpers.getIntField(dashboardTile, "iconRes"); if (ConfigUtils.M) { String iconPkg = (String) XposedHelpers.getObjectField(dashboardTile, "iconPkg"); if (!TextUtils.isEmpty(iconPkg)) { try { Drawable drawable = mActivity.getPackageManager().getResourcesForApplication(iconPkg).getDrawable(iconRes, null); if (!iconPkg.equals(PACKAGE_SETTINGS) && drawable != null) { // If this drawable is coming from outside Settings, tint it to match the color. TypedValue tintColorValue = new TypedValue(); mActivity.getResources().getValue(mActivity.getResources().getIdentifier("external_tile_icon_tint_color", "color", mActivity.getPackageName()), tintColorValue, true); // If tintColorValue is TYPE_ATTRIBUTE, resolve it if (tintColorValue.type == TypedValue.TYPE_ATTRIBUTE) { mActivity.getTheme().resolveAttribute(tintColorValue.data, tintColorValue, true); } drawable.setTintMode(android.graphics.PorterDuff.Mode.SRC_ATOP); drawable.setTint(tintColorValue.data); } return drawable; } catch (Throwable t) { XposedHook.logE(TAG, "Can't get icon for tile", t); return null; } } } if (iconRes > 0) { return mActivity.getDrawable(iconRes); } else { return null; } } public Object getTile(int position) { return mItems.get(position) != null ? mItems.get(position).tile : null; } @Override public DrawerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView; switch (viewType) { case TYPE_SPACER: itemView = inflate(mActivity, R.layout.drawer_spacer, parent, false); itemView.setEnabled(false); break; case TYPE_CATEGORY: itemView = inflate(mActivity, R.layout.drawer_category, parent, false); itemView.setEnabled(false); break; default: itemView = inflate(mActivity, R.layout.drawer_item, parent, false); } return new DrawerViewHolder(itemView); } @Override public void onBindViewHolder(DrawerViewHolder holder, int position) { int type = getItemViewType(position); if (type == TYPE_SPACER) return; ViewGroup itemView = (ViewGroup) holder.getItemView(); Item item = mItems.get(position); if (type == TYPE_TILE) { ((ImageView) itemView.findViewById(android.R.id.icon)).setImageDrawable(item.icon); } ((TextView) itemView.findViewById(android.R.id.title)).setText(item.label); } @Override public long getItemId(int position) { return position; } @Override public int getItemCount() { return mItems.size(); } @Override public int getItemViewType(int position) { Item item = mItems.get(position); if (item == null) { return TYPE_SPACER; } else if (item.icon == null) { return TYPE_CATEGORY; } else { return TYPE_TILE; } } private View inflate(Context context, int resource, ViewGroup root, boolean attachToRoot) { return LayoutInflater.from(context).inflate(ResourceUtils.getInstance(context).getLayout(resource), root, attachToRoot); } public void setSettingsActivityHelper(SettingsActivityHelper settingsActivityHelper) { mHelper = settingsActivityHelper; } private static class Item { public Drawable icon; public CharSequence label; public Object tile; } private class CategoriesUpdater extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { updateCategoriesInternal(); return null; } @Override protected void onPostExecute(Void aVoid) { notifyDataSetChanged(); if (mHelper != null) mHelper.updateDrawerLock(); } } public class DrawerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public DrawerViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); } public View getItemView() { return itemView; } @Override public void onClick(View v) { mHelper.onTileClicked(getTile(getAdapterPosition())); } } }