Addon list improvements (#575)

* Added disabled indicator on addon list

* Added menu options to hide disabled addons

* Code review changes
This commit is contained in:
Tomer Froumin 2018-09-14 18:59:17 +03:00 committed by Synced Synapse
parent 456ac6a107
commit f774f42700
9 changed files with 132 additions and 21 deletions

View File

@ -132,6 +132,10 @@ public class Settings {
public static final String KEY_PREF_TVSHOWS_SHOW_WATCHED_STATUS = "tvshows_show_watched_status";
public static final boolean DEFAULT_PREF_TVSHOWS_SHOW_WATCHED_STATUS = true;
// Filter disabled addons on addons list
public static final String KEY_PREF_ADDONS_FILTER_HIDE_DISABLED = "addons_filter_hide_disabled";
public static final boolean DEFAULT_PREF_ADDONS_FILTER_HIDE_DISABLED = false;
// Use hardware volume keys to control volume
public static final String KEY_PREF_USE_HARDWARE_VOLUME_KEYS = "pref_use_hardware_volume_keys";
public static final boolean DEFAULT_PREF_USE_HARDWARE_VOLUME_KEYS = true;

View File

@ -17,11 +17,16 @@ package org.xbmc.kore.ui.sections.addon;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@ -29,6 +34,7 @@ import android.widget.TextView;
import android.widget.Toast;
import org.xbmc.kore.R;
import org.xbmc.kore.Settings;
import org.xbmc.kore.host.HostManager;
import org.xbmc.kore.jsonrpc.ApiCallback;
import org.xbmc.kore.jsonrpc.method.Addons;
@ -63,6 +69,8 @@ public class AddonListFragment extends AbstractListFragment {
*/
private Handler callbackHandler = new Handler();
private static boolean hideDisabledAddons;
@Override
protected RecyclerViewEmptyViewSupport.OnItemClickListener createOnItemClickListener() {
return new RecyclerViewEmptyViewSupport.OnItemClickListener() {
@ -84,7 +92,7 @@ public class AddonListFragment extends AbstractListFragment {
@Override
public void onActivityCreated (Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(false);
setHasOptionsMenu(true);
if (getAdapter().getItemCount() == 0)
callGetAddonsAndSetup();
@ -116,6 +124,41 @@ public class AddonListFragment extends AbstractListFragment {
.show();
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.addon_list, menu);
// Setup filters
MenuItem hideDisabled = menu.findItem(R.id.action_hide_disabled);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
hideDisabledAddons = preferences.getBoolean(Settings.KEY_PREF_ADDONS_FILTER_HIDE_DISABLED, Settings.DEFAULT_PREF_ADDONS_FILTER_HIDE_DISABLED);
hideDisabled.setChecked(hideDisabledAddons);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
switch (item.getItemId()) {
case R.id.action_hide_disabled:
item.setChecked(!item.isChecked());
preferences.edit()
.putBoolean(Settings.KEY_PREF_ADDONS_FILTER_HIDE_DISABLED, item.isChecked())
.apply();
hideDisabledAddons = item.isChecked();
callGetAddonsAndSetup();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
public class AddonNameComparator implements Comparator<AddonType.Details>
{
public int compare(AddonType.Details left, AddonType.Details right) {
@ -156,13 +199,7 @@ public class AddonListFragment extends AbstractListFragment {
adapter.clear();
for (AddonType.Details addon : result) {
if (addon.type.equals(AddonType.Types.UNKNOWN) ||
addon.type.equals(AddonType.Types.XBMC_PYTHON_PLUGINSOURCE) ||
addon.type.equals(AddonType.Types.XBMC_PYTHON_SCRIPT) ||
addon.type.equals(AddonType.Types.XBMC_ADDON_AUDIO) ||
addon.type.equals(AddonType.Types.XBMC_ADDON_EXECUTABLE) ||
addon.type.equals(AddonType.Types.XBMC_ADDON_VIDEO) ||
addon.type.equals(AddonType.Types.XBMC_ADDON_IMAGE)) {
if (isAddonSupported(addon) && (!hideDisabledAddons || addon.enabled)) {
adapter.add(addon);
}
}
@ -188,6 +225,16 @@ public class AddonListFragment extends AbstractListFragment {
callbackHandler);
}
private boolean isAddonSupported(AddonType.Details addon) {
return (addon.type.equals(AddonType.Types.UNKNOWN) ||
addon.type.equals(AddonType.Types.XBMC_PYTHON_PLUGINSOURCE) ||
addon.type.equals(AddonType.Types.XBMC_PYTHON_SCRIPT) ||
addon.type.equals(AddonType.Types.XBMC_ADDON_AUDIO) ||
addon.type.equals(AddonType.Types.XBMC_ADDON_EXECUTABLE) ||
addon.type.equals(AddonType.Types.XBMC_ADDON_VIDEO) ||
addon.type.equals(AddonType.Types.XBMC_ADDON_IMAGE));
}
private static class AddonsAdapter extends RecyclerView.Adapter {
private HostManager hostManager;
@ -247,6 +294,7 @@ public class AddonListFragment extends AbstractListFragment {
TextView titleView;
TextView detailsView;
ImageView artView;
ImageView disabledView;
private static String author;
private static String version;
private HostManager hostManager;
@ -270,6 +318,7 @@ public class AddonListFragment extends AbstractListFragment {
titleView = itemView.findViewById(R.id.title);
detailsView = itemView.findViewById(R.id.details);
artView = itemView.findViewById(R.id.art);
disabledView = itemView.findViewById(R.id.disabled);
itemView.setTag(this);
}
@ -288,6 +337,7 @@ public class AddonListFragment extends AbstractListFragment {
titleView.setText(dataHolder.getTitle());
detailsView.setText(addonDetails.summary);
disabledView.setVisibility(addonDetails.enabled ? View.INVISIBLE : View.VISIBLE);
UIUtils.loadImageWithCharacterAvatar(context, hostManager,
addonDetails.thumbnail, dataHolder.getTitle(),

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z"/>
</vector>

View File

@ -21,34 +21,49 @@
android:layout_height="wrap_content"
style="@style/Widget.CardView">
<LinearLayout
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:layout_height="wrap_content">
<ImageView
android:id="@+id/art"
android:layout_width="@dimen/addonlist_art_width"
android:layout_height="@dimen/addonlist_art_heigth"
android:contentDescription="@string/poster"/>
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:contentDescription="@string/poster"
android:scaleType="centerCrop"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.Medialist.Title"
android:paddingTop="0dp"/>
android:layout_toRightOf="@id/art"
android:layout_toEndOf="@id/art"
android:layout_alignTop="@id/art"
style="@style/TextAppearance.Medialist.Title"/>
<TextView
android:id="@+id/details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/title"
android:layout_alignStart="@id/title"
android:layout_below="@id/title"
style="@style/TextAppearance.Medialist.Details"
android:paddingBottom="0dp"/>
</LinearLayout>
</LinearLayout>
<ImageView
android:id="@+id/disabled"
android:layout_width="@dimen/default_icon_size"
android:layout_height="@dimen/default_icon_size"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
style="@style/Widget.Button.Borderless"
android:padding="@dimen/default_icon_padding"
android:src="?attr/iconDisabled"
android:contentDescription="@string/addon_disabled"/>
</RelativeLayout>
</android.support.v7.widget.CardView>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 Synced Synapse. All rights reserved.
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.
-->
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group
android:checkableBehavior="all">
<item
android:id="@+id/action_hide_disabled"
android:title="@string/hide_disabled"
app:showAsAction="never"/>
</group>
</menu>

View File

@ -323,6 +323,7 @@
<!-- Filters on list menus -->
<string name="hide_watched">הסתרת אלו שראיתי</string>
<string name="hide_disabled">הסתרת הרחבות מנוטרלות</string>
<string name="sort_order">סידור</string>
<string name="sort_by_name">לפי שם</string>
<string name="sort_by_year">לפי שנה </string>

View File

@ -110,6 +110,7 @@
<attr name="iconAddToQueue" format="reference" />
<attr name="iconInfoWWW" format="reference" />
<attr name="iconSeen" format="reference" />
<attr name="iconDisabled" format="reference" />
<attr name="iconCollapse" format="reference" />
<attr name="iconExpand" format="reference" />

View File

@ -322,6 +322,7 @@
<!-- Filters on list menus -->
<string name="hide_watched">Hide watched</string>
<string name="hide_disabled">Hide disabled</string>
<string name="sort_order">Sort</string>
<string name="sort_by_name">By name</string>
<string name="sort_by_year">By year</string>

View File

@ -151,6 +151,7 @@
<item name="iconAddToQueue">@drawable/ic_queue_white_24dp</item>
<item name="iconInfoWWW">@drawable/ic_open_in_new_white_24dp</item>
<item name="iconSeen">@drawable/ic_done_white_24dp</item>
<item name="iconDisabled">@drawable/ic_cancel_white_24dp</item>
<item name="iconCollapse">@drawable/ic_expand_less_white_24dp</item>
<item name="iconExpand">@drawable/ic_expand_more_white_24dp</item>
@ -299,6 +300,7 @@
<item name="iconAddToQueue">@drawable/ic_queue_white_24dp</item>
<item name="iconInfoWWW">@drawable/ic_open_in_new_white_24dp</item>
<item name="iconSeen">@drawable/ic_done_white_24dp</item>
<item name="iconDisabled">@drawable/ic_cancel_white_24dp</item>
<item name="iconCollapse">@drawable/ic_expand_less_white_24dp</item>
<item name="iconExpand">@drawable/ic_expand_more_white_24dp</item>