0
0
mirror of https://github.com/mediathekview/zapp.git synced 2024-09-19 20:02:17 +02:00

Refactor pillow buttons into their own fragment

This commit is contained in:
Christine Emrich 2018-05-29 20:49:14 +02:00
parent 3b4f1c8304
commit 2e6a040465
12 changed files with 325 additions and 100 deletions

View File

@ -0,0 +1,12 @@
package de.christinecoenen.code.zapp.app.mediathek.api.request;
public class Interval {
private int start;
private int end;
public Interval(int start, int end) {
this.start = start;
this.end = end;
}
}

View File

@ -27,10 +27,13 @@ public class QueryRequest implements Serializable {
private final transient TextQuery searchQuery = new TextQuery()
.addField(Field.TITLE)
.addField(Field.TOPIC);
private final transient RangeQuery lengthQuery = new RangeQuery()
.setField(Field.DURATION)
.setGte("0");
private final BoolQuery body = new BoolQuery()
.setNotQueries(EXCLUDE_CHANNELS_QUERY)
.setMustQueries(noSearchQuery)
.setMustQueries(noSearchQuery, lengthQuery)
.setFilterQueries(EXCLUDE_FUTURE_QUERY);
private List<Sort> sort;
@ -39,14 +42,19 @@ public class QueryRequest implements Serializable {
public QueryRequest setSimpleSearch(String queryString) {
if (TextUtils.isEmpty(queryString)) {
body.setMustQueries(noSearchQuery);
body.setMustQueries(noSearchQuery, lengthQuery);
} else {
searchQuery.setText(queryString);
body.setMustQueries(searchQuery);
body.setMustQueries(searchQuery, lengthQuery);
}
return this;
}
public QueryRequest setMinLength(int minLengthSeconds) {
lengthQuery.setGte(String.valueOf(minLengthSeconds));
return this;
}
public QueryRequest excludeChannels(String... channels) {
TextQuery[] dynamicExcludeChannelQueries = new TextQuery[channels.length + 1];
int i = 0;

View File

@ -0,0 +1,14 @@
package de.christinecoenen.code.zapp.app.mediathek.api.request.query;
import java.util.ArrayList;
import java.util.List;
import de.christinecoenen.code.zapp.app.mediathek.api.request.Interval;
public class IntervalList {
private List<Interval> intervals = new ArrayList<>();
//public
}

View File

@ -9,31 +9,23 @@ import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ToggleButton;
import java.util.ArrayList;
import java.util.Objects;
import butterknife.BindArray;
import butterknife.BindView;
import butterknife.ButterKnife;
import de.christinecoenen.code.zapp.R;
import de.christinecoenen.code.zapp.utils.view.PillowButtonScrollerFragment;
public class MediathekListFilterFragment extends Fragment {
private static final String SHARED_PREFS_KEY_FILTER_OPEN = "SHARED_PREFS_FRILTER_OPEN";
private static final String SHARED_PREFS_KEY_FILTER_CHANNEL_SELECTED_ = "SHARED_PREFS_KEY_FILTER_CHANNEL_SELECTED_";
@BindArray(R.array.mediathek_channels)
protected String[] channelNames;
@BindView(R.id.container_channel_buttons)
protected LinearLayout channelButtonContainer;
private Listener listener;
private SharedPreferences sharedPreferences;
private PillowButtonScrollerFragment channelFilter;
private PillowButtonScrollerFragment lengthFilter;
public MediathekListFilterFragment() {
// Required empty public constructor
@ -52,16 +44,12 @@ public class MediathekListFilterFragment extends Fragment {
}
public String[] getExcludedChannels() {
ArrayList<String> excludedChannels = new ArrayList<>();
return channelFilter.getExcludedKeys();
}
for (int i = 0; i < channelButtonContainer.getChildCount(); i++) {
ToggleButton channelButton = (ToggleButton) channelButtonContainer.getChildAt(i);
if (!channelButton.isChecked()) {
excludedChannels.add(channelButton.getText().toString());
}
}
return excludedChannels.toArray(new String[excludedChannels.size()]);
public int getMinLength() {
// TODO: expose length intervals
return 0;
}
@Override
@ -75,9 +63,13 @@ public class MediathekListFilterFragment extends Fragment {
View view = inflater.inflate(R.layout.fragment_mediathek_list_filter, container, false);
ButterKnife.bind(this, view);
for (String channelName : channelNames) {
addChannelButton(inflater, channelName);
}
channelFilter = (PillowButtonScrollerFragment) getChildFragmentManager()
.findFragmentById(R.id.fragment_channel_filter);
channelFilter.setListener(() -> listener.onChannelsChanged());
lengthFilter = (PillowButtonScrollerFragment) getChildFragmentManager()
.findFragmentById(R.id.fragment_length_filter);
lengthFilter.setListener(() -> listener.onLengthChanged());
return view;
}
@ -131,57 +123,9 @@ public class MediathekListFilterFragment extends Fragment {
sharedPreferences.edit().putBoolean(SHARED_PREFS_KEY_FILTER_OPEN, false).apply();
}
private void addChannelButton(LayoutInflater inflater, String channelName) {
ToggleButton channelButton = (ToggleButton) inflater.inflate(
R.layout.fragment_mediathek_list_filter_toggle_button,
channelButtonContainer, false);
channelButton.setTextOff(channelName);
channelButton.setTextOn(channelName);
boolean isChecked = sharedPreferences.getBoolean(SHARED_PREFS_KEY_FILTER_CHANNEL_SELECTED_ + channelName, true);
channelButton.setChecked(isChecked);
channelButton.setOnClickListener(v -> onChannelButtonClicked((ToggleButton) v, channelName));
channelButton.setOnLongClickListener(v -> onChannelButtonLongClicked((ToggleButton) v, channelName));
channelButtonContainer.addView(channelButton);
}
private void onChannelButtonClicked(ToggleButton button, String channelName) {
setChannelButton(button, channelName, button.isChecked());
if (listener != null) {
listener.onChannelsChanged();
}
}
private boolean onChannelButtonLongClicked(ToggleButton button, String channelName) {
boolean isOnlyOneChecked = getExcludedChannels().length >= channelButtonContainer.getChildCount() - 1;
boolean doOthersCheck = button.isChecked() && isOnlyOneChecked;
for (int i = 0; i < channelButtonContainer.getChildCount(); i++) {
ToggleButton channelButton = (ToggleButton) channelButtonContainer.getChildAt(i);
if (channelButton != button) {
setChannelButton(channelButton, channelButton.getTextOn().toString(), doOthersCheck);
}
}
setChannelButton(button, channelName, true);
if (listener != null) {
listener.onChannelsChanged();
}
return true;
}
private void setChannelButton(ToggleButton button, String channelName, boolean checked) {
sharedPreferences
.edit()
.putBoolean(SHARED_PREFS_KEY_FILTER_CHANNEL_SELECTED_ + channelName, checked)
.apply();
button.setChecked(checked);
}
public interface Listener {
void onLengthChanged();
void onChannelsChanged();
}
}

View File

@ -212,6 +212,16 @@ public class MediathekListFragment extends Fragment implements
loadItems(0, true);
}
@Override
public void onLengthChanged() {
setMinLengthFilter();
loadItems(0, true);
}
private void setMinLengthFilter() {
queryRequest.setMinLength(filter.getMinLength() * 60);
}
private void setChannelFilter() {
queryRequest.excludeChannels(filter.getExcludedChannels());
}

View File

@ -0,0 +1,195 @@
package de.christinecoenen.code.zapp.utils.view;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ToggleButton;
import java.util.ArrayList;
import java.util.Objects;
import butterknife.BindView;
import butterknife.ButterKnife;
import de.christinecoenen.code.zapp.R;
public class PillowButtonScrollerFragment extends Fragment {
private static final String ARG_SHARED_PREFS_PREFIX = "ARG_SHARED_PREFS_PREFIX";
private static final String ARG_KEY_LIST = "ARG_KEY_LIST";
private static final String ARG_LABEL_LIST = "ARG_LABEL_LIST";
@BindView(R.id.container_toggle_buttons)
protected LinearLayout buttonContainer;
private String sharedPrefsPrefix;
private String[] keyList;
private String[] labelList;
private Listener listener;
private SharedPreferences sharedPreferences;
public PillowButtonScrollerFragment() {
// Required empty public constructor
}
public static PillowButtonScrollerFragment newInstance(String sharedPrefsPrefix, String[] keyList, String[] labelList) {
PillowButtonScrollerFragment fragment = new PillowButtonScrollerFragment();
Bundle args = new Bundle();
args.putString(ARG_SHARED_PREFS_PREFIX, sharedPrefsPrefix);
args.putStringArray(ARG_KEY_LIST, keyList);
args.putStringArray(ARG_LABEL_LIST, labelList);
fragment.setArguments(args);
return fragment;
}
public String[] getExcludedKeys() {
ArrayList<String> excludedKeys = new ArrayList<>();
for (int i = 0; i < buttonContainer.getChildCount(); i++) {
ToggleButton button = (ToggleButton) buttonContainer.getChildAt(i);
if (!button.isChecked()) {
excludedKeys.add(keyList[i]);
}
}
return excludedKeys.toArray(new String[excludedKeys.size()]);
}
public String[] getIncludedKeys() {
ArrayList<String> includedKeys = new ArrayList<>();
for (int i = 0; i < buttonContainer.getChildCount(); i++) {
ToggleButton button = (ToggleButton) buttonContainer.getChildAt(i);
if (button.isChecked()) {
includedKeys.add(keyList[i]);
}
}
return includedKeys.toArray(new String[includedKeys.size()]);
}
public void setListener(Listener listener) {
this.listener = listener;
}
@Override
public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) {
super.onInflate(context, attrs, savedInstanceState);
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.PillowButtonScrollerFragment);
int keyListResId = attributes.getResourceId(R.styleable.PillowButtonScrollerFragment_key_list_res_id, 0);
int labelListResId = attributes.getResourceId(R.styleable.PillowButtonScrollerFragment_label_list_res_id, 0);
sharedPrefsPrefix = attributes.getString(R.styleable.PillowButtonScrollerFragment_shared_prefs_prefix);
if (keyListResId == 0 || labelListResId == 0 || sharedPrefsPrefix == null) {
throw new IllegalArgumentException("shared_prefs_prefix, key_list_res_id and label_list_res_id habe to set in xml layout");
}
keyList = getResources().getStringArray(keyListResId);
labelList = getResources().getStringArray(labelListResId);
attributes.recycle();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
sharedPrefsPrefix = getArguments().getString(ARG_SHARED_PREFS_PREFIX);
keyList = getArguments().getStringArray(ARG_KEY_LIST);
labelList = getArguments().getStringArray(ARG_LABEL_LIST);
}
sharedPreferences = Objects.requireNonNull(getActivity()).getPreferences(Context.MODE_PRIVATE);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_pillow_button_scroller, container, false);
ButterKnife.bind(this, view);
for (int i = 0; i< labelList.length; i++) {
addButton(inflater, i);
}
return view;
}
@Override
public void onDetach() {
super.onDetach();
listener = null;
}
private void addButton(LayoutInflater inflater, int index) {
String label = labelList[index];
String key = labelList[index];
ToggleButton channelButton = (ToggleButton) inflater.inflate(
R.layout.fragment_pillow_button_scroller_toggle_button,
buttonContainer, false);
channelButton.setTextOff(label);
channelButton.setTextOn(label);
channelButton.setTag(index);
boolean isChecked = sharedPreferences.getBoolean(sharedPrefsPrefix + "_" + key, true);
channelButton.setChecked(isChecked);
channelButton.setOnClickListener(this::onButtonClicked);
channelButton.setOnLongClickListener(this::onButtonLongClicked);
buttonContainer.addView(channelButton);
}
private void onButtonClicked(View view) {
ToggleButton button = (ToggleButton) view;
setChannelButton(button, button.isChecked());
if (listener != null) {
listener.onValuesChanged();
}
}
private boolean onButtonLongClicked(View view) {
ToggleButton button = (ToggleButton) view;
boolean isOnlyOneChecked = getIncludedKeys().length <= 1;
boolean doOthersCheck = button.isChecked() && isOnlyOneChecked;
for (int i = 0; i < buttonContainer.getChildCount(); i++) {
ToggleButton channelButton = (ToggleButton) buttonContainer.getChildAt(i);
if (channelButton != button) {
setChannelButton(channelButton, doOthersCheck);
}
}
setChannelButton(button, true);
if (listener != null) {
listener.onValuesChanged();
}
return true;
}
private void setChannelButton(ToggleButton button, boolean checked) {
int index = (int) button.getTag();
sharedPreferences
.edit()
.putBoolean(sharedPrefsPrefix + "_" + keyList[index], checked)
.apply();
button.setChecked(checked);
}
public interface Listener {
void onValuesChanged();
}
}

View File

@ -28,54 +28,52 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fragment_mediathek_filter_duration"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent" />
app:layout_constraintBottom_toBottomOf="@+id/fragment_length_filter"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/fragment_length_filter" />
<SeekBar
android:id="@+id/seekbar_duration"
<fragment
android:id="@+id/fragment_length_filter"
android:name="de.christinecoenen.code.zapp.utils.view.PillowButtonScrollerFragment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:max="300"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/label_duration"
android:layout_marginTop="8dp"
app:key_list_res_id="@array/mediathek_length_keys"
app:label_list_res_id="@array/mediathek_length_labels"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/barrier_labels_end"
app:layout_constraintTop_toTopOf="@+id/label_duration" />
app:layout_constraintTop_toBottomOf="@+id/fragment_channel_filter"
app:shared_prefs_prefix="SHARED_PREFS_KEY_FILTER_LENGTH_SELECTED" />
<android.support.constraint.Barrier
android:id="@+id/barrier_duration_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="label_duration,seekbar_duration" />
app:constraint_referenced_ids="label_duration,fragment_length_filter" />
<TextView
android:id="@+id/label_channels"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fragment_mediathek_filter_channel"
app:layout_constraintBottom_toBottomOf="@id/channel_scroller"
app:layout_constraintBottom_toBottomOf="@id/fragment_channel_filter"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/channel_scroller" />
app:layout_constraintTop_toTopOf="@id/fragment_channel_filter" />
<HorizontalScrollView
android:id="@+id/channel_scroller"
<fragment
android:id="@+id/fragment_channel_filter"
android:name="de.christinecoenen.code.zapp.utils.view.PillowButtonScrollerFragment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:scrollbars="none"
app:key_list_res_id="@array/mediathek_channel_keys"
app:label_list_res_id="@array/mediathek_channel_keys"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/barrier_labels_end"
app:layout_constraintTop_toBottomOf="@id/barrier_duration_bottom">
<LinearLayout
android:id="@+id/container_channel_buttons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" />
</HorizontalScrollView>
app:layout_constraintTop_toTopOf="parent"
app:shared_prefs_prefix="SHARED_PREFS_KEY_FILTER_CHANNEL_SELECTED" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/channel_scroller"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
tools:context=".utils.view.PillowButtonScrollerFragment">
<LinearLayout
android:id="@+id/container_toggle_buttons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" />
</HorizontalScrollView>

View File

@ -2,7 +2,7 @@
<resources>
<array name="empty" />
<string-array name="mediathek_channels">
<string-array name="mediathek_channel_keys">
<item>ARD</item>
<item>ZDF</item>
<item>BR</item>
@ -24,4 +24,20 @@
<item>SRF.Podcast</item>
</string-array>
<string-array name="mediathek_length_keys">
<item>0_6</item>
<item>6_15</item>
<item>15_35</item>
<item>35_65</item>
<item>65_1000</item>
</string-array>
<string-array name="mediathek_length_labels">
<item>@string/fragment_mediathek_length_label_0</item>
<item>@string/fragment_mediathek_length_label_1</item>
<item>@string/fragment_mediathek_length_label_2</item>
<item>@string/fragment_mediathek_length_label_3</item>
<item>@string/fragment_mediathek_length_label_4</item>
</string-array>
</resources>

View File

@ -9,4 +9,10 @@
<attr name="metaButtonBarButtonStyle" format="reference" />
</declare-styleable>
<declare-styleable name="PillowButtonScrollerFragment">
<attr name="shared_prefs_prefix" format="string"/>
<attr name="key_list_res_id" format="reference"/>
<attr name="label_list_res_id" format="reference"/>
</declare-styleable>
</resources>

View File

@ -38,6 +38,11 @@
<string name="fragment_mediathek_filter_duration">Dauer</string>
<string name="fragment_mediathek_filter_channel">Sender</string>
<string name="fragment_mediathek_length_label_0">06m</string>
<string name="fragment_mediathek_length_label_1">615m</string>
<string name="fragment_mediathek_length_label_2">1535m</string>
<string name="fragment_mediathek_length_label_3">3565m</string>
<string name="fragment_mediathek_length_label_4">65+</string>
<string name="fragment_mediathek_download_started">Download von \'%s\' gestartet…</string>