Refactored MediaFileListFragment to support multi-/single-columns
Refactored AbstractListFragment to make it more generic and allow it to be used by MediaFileListFragment. This adds support for switching between a single- and multicolumn view. Created new abstract class AbstractCursorListFragment for list fragments using a cursoradapter.
This commit is contained in:
parent
e5a1e97b8d
commit
8bfe2665dd
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
* Copyright 2015 Martijn Brekhof. 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.
|
||||
*/
|
||||
|
||||
package org.xbmc.kore.ui;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.SearchView;
|
||||
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.CursorAdapter;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.xbmc.kore.R;
|
||||
import org.xbmc.kore.host.HostInfo;
|
||||
import org.xbmc.kore.host.HostManager;
|
||||
import org.xbmc.kore.jsonrpc.ApiException;
|
||||
import org.xbmc.kore.jsonrpc.event.MediaSyncEvent;
|
||||
import org.xbmc.kore.service.LibrarySyncService;
|
||||
import org.xbmc.kore.service.SyncUtils;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
|
||||
import de.greenrobot.event.EventBus;
|
||||
|
||||
public abstract class AbstractCursorListFragment extends AbstractListFragment
|
||||
implements LoaderManager.LoaderCallbacks<Cursor>,
|
||||
SyncUtils.OnServiceListener,
|
||||
SearchView.OnQueryTextListener,
|
||||
SwipeRefreshLayout.OnRefreshListener {
|
||||
private static final String TAG = LogUtils.makeLogTag(AbstractCursorListFragment.class);
|
||||
|
||||
private ServiceConnection serviceConnection;
|
||||
|
||||
private HostInfo hostInfo;
|
||||
private EventBus bus;
|
||||
|
||||
private CursorAdapter adapter;
|
||||
|
||||
// Loader IDs
|
||||
private static final int LOADER = 0;
|
||||
|
||||
// The search filter to use in the loader
|
||||
private String searchFilter = null;
|
||||
|
||||
abstract protected CursorLoader createCursorLoader();
|
||||
|
||||
@TargetApi(16)
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View root = super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
bus = EventBus.getDefault();
|
||||
HostManager hostManager = HostManager.getInstance(getActivity());
|
||||
hostInfo = hostManager.getHostInfo();
|
||||
|
||||
swipeRefreshLayout.setEnabled(true);
|
||||
swipeRefreshLayout.setOnRefreshListener(this);
|
||||
|
||||
adapter = (CursorAdapter) getAdapter();
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated (Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
getLoaderManager().initLoader(LOADER, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
serviceConnection = SyncUtils.connectToLibrarySyncService(getActivity(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
bus.register(this);
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
bus.unregister(this);
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
SyncUtils.disconnectFromLibrarySyncService(getActivity(), serviceConnection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.abstractcursorlistfragment, menu);
|
||||
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch(item.getItemId()) {
|
||||
case R.id.action_refresh:
|
||||
onRefresh();
|
||||
break;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Swipe refresh layout callback
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
if (hostInfo != null) {
|
||||
showRefreshAnimation();
|
||||
onSwipeRefresh();
|
||||
} else {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
Toast.makeText(getActivity(), R.string.no_xbmc_configured, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should return the {@link LibrarySyncService} SyncType that
|
||||
* this list initiates
|
||||
* @return {@link LibrarySyncService} SyncType
|
||||
*/
|
||||
abstract protected String getListSyncType();
|
||||
|
||||
/**
|
||||
* Event bus post. Called when the syncing process ended
|
||||
*
|
||||
* @param event Refreshes data
|
||||
*/
|
||||
public void onEventMainThread(MediaSyncEvent event) {
|
||||
onSyncProcessEnded(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called each time a MediaSyncEvent is received.
|
||||
* @param event
|
||||
*/
|
||||
protected void onSyncProcessEnded(MediaSyncEvent event) {
|
||||
boolean silentSync = false;
|
||||
if (event.syncExtras != null) {
|
||||
silentSync = event.syncExtras.getBoolean(LibrarySyncService.SILENT_SYNC, false);
|
||||
}
|
||||
|
||||
if (event.syncType.equals(getListSyncType())) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
if (event.status == MediaSyncEvent.STATUS_SUCCESS) {
|
||||
refreshList();
|
||||
if (!silentSync) {
|
||||
Toast.makeText(getActivity(), R.string.sync_successful, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
} else if (!silentSync) {
|
||||
String msg = (event.errorCode == ApiException.API_ERROR) ?
|
||||
String.format(getString(R.string.error_while_syncing), event.errorMessage) :
|
||||
getString(R.string.unable_to_connect_to_xbmc);
|
||||
Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(LibrarySyncService librarySyncService) {
|
||||
if(SyncUtils.isLibrarySyncing(
|
||||
librarySyncService,
|
||||
HostManager.getInstance(getActivity()).getHostInfo(),
|
||||
getListSyncType())) {
|
||||
showRefreshAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
protected void onSwipeRefresh() {
|
||||
LogUtils.LOGD(TAG, "Swipe, starting sync for: " + getListSyncType());
|
||||
// Start the syncing process
|
||||
Intent syncIntent = new Intent(this.getActivity(), LibrarySyncService.class);
|
||||
syncIntent.putExtra(getListSyncType(), true);
|
||||
getActivity().startService(syncIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search view callbacks
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
searchFilter = newText;
|
||||
getLoaderManager().restartLoader(LOADER, null, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String newText) {
|
||||
// All is handled in onQueryTextChange
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loader callbacks
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
|
||||
return createCursorLoader();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
|
||||
adapter.swapCursor(cursor);
|
||||
// To prevent the empty text from appearing on the first load, set it now
|
||||
emptyView.setText(getString(R.string.swipe_down_to_refresh));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> cursorLoader) {
|
||||
adapter.swapCursor(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return text entered in searchview
|
||||
*/
|
||||
public String getSearchFilter() {
|
||||
return searchFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to reload the items in the list
|
||||
*/
|
||||
public void refreshList() {
|
||||
getLoaderManager().restartLoader(LOADER, null, this);
|
||||
}
|
||||
}
|
|
@ -17,19 +17,12 @@
|
|||
package org.xbmc.kore.ui;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
|
@ -38,44 +31,21 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.CursorAdapter;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.GridView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.xbmc.kore.R;
|
||||
import org.xbmc.kore.Settings;
|
||||
import org.xbmc.kore.host.HostInfo;
|
||||
import org.xbmc.kore.host.HostManager;
|
||||
import org.xbmc.kore.jsonrpc.ApiException;
|
||||
import org.xbmc.kore.jsonrpc.event.MediaSyncEvent;
|
||||
import org.xbmc.kore.service.LibrarySyncService;
|
||||
import org.xbmc.kore.service.SyncUtils;
|
||||
import org.xbmc.kore.utils.LogUtils;
|
||||
import org.xbmc.kore.utils.Utils;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.InjectView;
|
||||
import de.greenrobot.event.EventBus;
|
||||
|
||||
public abstract class AbstractListFragment extends Fragment
|
||||
implements LoaderManager.LoaderCallbacks<Cursor>,
|
||||
SyncUtils.OnServiceListener,
|
||||
SearchView.OnQueryTextListener,
|
||||
SwipeRefreshLayout.OnRefreshListener {
|
||||
public abstract class AbstractListFragment extends Fragment {
|
||||
private static final String TAG = LogUtils.makeLogTag(AbstractListFragment.class);
|
||||
|
||||
private ServiceConnection serviceConnection;
|
||||
private CursorAdapter adapter;
|
||||
|
||||
private HostInfo hostInfo;
|
||||
private EventBus bus;
|
||||
|
||||
// Loader IDs
|
||||
private static final int LOADER = 0;
|
||||
|
||||
// The search filter to use in the loader
|
||||
private String searchFilter = null;
|
||||
private BaseAdapter adapter;
|
||||
|
||||
private boolean gridViewUsesMultipleColumns;
|
||||
|
||||
|
@ -84,8 +54,7 @@ public abstract class AbstractListFragment extends Fragment
|
|||
@InjectView(android.R.id.empty) TextView emptyView;
|
||||
|
||||
abstract protected AdapterView.OnItemClickListener createOnItemClickListener();
|
||||
abstract protected CursorAdapter createAdapter();
|
||||
abstract protected CursorLoader createCursorLoader();
|
||||
abstract protected BaseAdapter createAdapter();
|
||||
|
||||
@TargetApi(16)
|
||||
@Nullable
|
||||
|
@ -94,22 +63,25 @@ public abstract class AbstractListFragment extends Fragment
|
|||
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_generic_media_list, container, false);
|
||||
ButterKnife.inject(this, root);
|
||||
|
||||
bus = EventBus.getDefault();
|
||||
HostManager hostManager = HostManager.getInstance(getActivity());
|
||||
hostInfo = hostManager.getHostInfo();
|
||||
swipeRefreshLayout.setEnabled(false);
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener(this);
|
||||
gridView.setEmptyView(emptyView);
|
||||
gridView.setOnItemClickListener(createOnItemClickListener());
|
||||
|
||||
// Configure the adapter and start the loader
|
||||
adapter = createAdapter();
|
||||
gridView.setAdapter(adapter);
|
||||
|
||||
//Listener added to be able to determine if multiple-columns is at all possible for the current grid
|
||||
//We use this information to enable/disable the menu item to switch between multiple and single columns
|
||||
gridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
if(gridView.getNumColumns() > 1) {
|
||||
if (gridView.getNumColumns() > 1) {
|
||||
gridViewUsesMultipleColumns = true;
|
||||
}
|
||||
|
||||
if(Utils.isJellybeanOrLater()) {
|
||||
if (Utils.isJellybeanOrLater()) {
|
||||
gridView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
} else {
|
||||
gridView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||
|
@ -119,47 +91,11 @@ public abstract class AbstractListFragment extends Fragment
|
|||
getActivity().invalidateOptionsMenu();
|
||||
}
|
||||
});
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated (Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
gridView.setEmptyView(emptyView);
|
||||
gridView.setOnItemClickListener(createOnItemClickListener());
|
||||
|
||||
// Configure the adapter and start the loader
|
||||
adapter = createAdapter();
|
||||
gridView.setAdapter(adapter);
|
||||
|
||||
getLoaderManager().initLoader(LOADER, null, this);
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
serviceConnection = SyncUtils.connectToLibrarySyncService(getActivity(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
bus.register(this);
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
bus.unregister(this);
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
SyncUtils.disconnectFromLibrarySyncService(getActivity(), serviceConnection);
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -193,9 +129,6 @@ public abstract class AbstractListFragment extends Fragment
|
|||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch(item.getItemId()) {
|
||||
case R.id.action_refresh:
|
||||
onRefresh();
|
||||
break;
|
||||
case R.id.action_multi_single_columns:
|
||||
toggleAmountOfColumns(item);
|
||||
break;
|
||||
|
@ -219,139 +152,6 @@ public abstract class AbstractListFragment extends Fragment
|
|||
adapter.notifyDataSetChanged(); //force gridView to redraw
|
||||
}
|
||||
|
||||
/**
|
||||
* Swipe refresh layout callback
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
if (hostInfo != null) {
|
||||
showRefreshAnimation();
|
||||
onSwipeRefresh();
|
||||
} else {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
Toast.makeText(getActivity(), R.string.no_xbmc_configured, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should return the {@link org.xbmc.kore.service.LibrarySyncService} SyncType that
|
||||
* this list initiates
|
||||
* @return {@link org.xbmc.kore.service.LibrarySyncService} SyncType
|
||||
*/
|
||||
abstract protected String getListSyncType();
|
||||
|
||||
/**
|
||||
* Event bus post. Called when the syncing process ended
|
||||
*
|
||||
* @param event Refreshes data
|
||||
*/
|
||||
public void onEventMainThread(MediaSyncEvent event) {
|
||||
onSyncProcessEnded(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called each time a MediaSyncEvent is received.
|
||||
* @param event
|
||||
*/
|
||||
protected void onSyncProcessEnded(MediaSyncEvent event) {
|
||||
boolean silentSync = false;
|
||||
if (event.syncExtras != null) {
|
||||
silentSync = event.syncExtras.getBoolean(LibrarySyncService.SILENT_SYNC, false);
|
||||
}
|
||||
|
||||
if (event.syncType.equals(getListSyncType())) {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
if (event.status == MediaSyncEvent.STATUS_SUCCESS) {
|
||||
refreshList();
|
||||
if (!silentSync) {
|
||||
Toast.makeText(getActivity(), R.string.sync_successful, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
} else if (!silentSync) {
|
||||
String msg = (event.errorCode == ApiException.API_ERROR) ?
|
||||
String.format(getString(R.string.error_while_syncing), event.errorMessage) :
|
||||
getString(R.string.unable_to_connect_to_xbmc);
|
||||
Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(LibrarySyncService librarySyncService) {
|
||||
if(SyncUtils.isLibrarySyncing(
|
||||
librarySyncService,
|
||||
HostManager.getInstance(getActivity()).getHostInfo(),
|
||||
getListSyncType())) {
|
||||
showRefreshAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
protected void onSwipeRefresh() {
|
||||
LogUtils.LOGD(TAG, "Swipe, starting sync for: " + getListSyncType());
|
||||
// Start the syncing process
|
||||
Intent syncIntent = new Intent(this.getActivity(), LibrarySyncService.class);
|
||||
syncIntent.putExtra(getListSyncType(), true);
|
||||
getActivity().startService(syncIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search view callbacks
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
searchFilter = newText;
|
||||
getLoaderManager().restartLoader(LOADER, null, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String newText) {
|
||||
// All is handled in onQueryTextChange
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loader callbacks
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
|
||||
return createCursorLoader();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
|
||||
adapter.swapCursor(cursor);
|
||||
// To prevent the empty text from appearing on the first load, set it now
|
||||
emptyView.setText(getString(R.string.swipe_down_to_refresh));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> cursorLoader) {
|
||||
adapter.swapCursor(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return text entered in searchview
|
||||
*/
|
||||
public String getSearchFilter() {
|
||||
return searchFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to reload the items in the list
|
||||
*/
|
||||
public void refreshList() {
|
||||
getLoaderManager().restartLoader(LOADER, null, this);
|
||||
}
|
||||
|
||||
public void showRefreshAnimation() {
|
||||
/**
|
||||
* Fixes issue with refresh animation not showing when using appcompat library (from version 20?)
|
||||
|
@ -364,4 +164,8 @@ public abstract class AbstractListFragment extends Fragment
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
public BaseAdapter getAdapter() {
|
||||
return adapter;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ import org.xbmc.kore.utils.Utils;
|
|||
/**
|
||||
* Fragment that presents the albums list
|
||||
*/
|
||||
public class AlbumListFragment extends AbstractListFragment {
|
||||
public class AlbumListFragment extends AbstractCursorListFragment {
|
||||
private static final String TAG = LogUtils.makeLogTag(AlbumListFragment.class);
|
||||
|
||||
public interface OnAlbumSelectedListener {
|
||||
|
|
|
@ -41,7 +41,6 @@ import android.widget.TextView;
|
|||
import org.xbmc.kore.R;
|
||||
import org.xbmc.kore.host.HostInfo;
|
||||
import org.xbmc.kore.host.HostManager;
|
||||
import org.xbmc.kore.jsonrpc.method.Playlist;
|
||||
import org.xbmc.kore.jsonrpc.type.PlaylistType;
|
||||
import org.xbmc.kore.provider.MediaContract;
|
||||
import org.xbmc.kore.provider.MediaDatabase;
|
||||
|
@ -54,7 +53,7 @@ import org.xbmc.kore.utils.Utils;
|
|||
/**
|
||||
* Fragment that presents the artists list
|
||||
*/
|
||||
public class ArtistListFragment extends AbstractListFragment {
|
||||
public class ArtistListFragment extends AbstractCursorListFragment {
|
||||
private static final String TAG = LogUtils.makeLogTag(ArtistListFragment.class);
|
||||
|
||||
public interface OnArtistSelectedListener {
|
||||
|
|
|
@ -50,7 +50,7 @@ import org.xbmc.kore.utils.UIUtils;
|
|||
/**
|
||||
* Fragment that presents the album genres list
|
||||
*/
|
||||
public class AudioGenresListFragment extends AbstractListFragment {
|
||||
public class AudioGenresListFragment extends AbstractCursorListFragment {
|
||||
private static final String TAG = LogUtils.makeLogTag(AudioGenresListFragment.class);
|
||||
|
||||
public interface OnAudioGenreSelectedListener {
|
||||
|
|
|
@ -21,15 +21,12 @@ import android.os.Bundle;
|
|||
import android.os.Handler;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.PopupMenu;
|
||||
|
@ -56,13 +53,10 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.InjectView;
|
||||
|
||||
/**
|
||||
* Presents a list of files of different types (Video/Music)
|
||||
*/
|
||||
public class MediaFileListFragment extends Fragment {
|
||||
public class MediaFileListFragment extends AbstractListFragment {
|
||||
private static final String TAG = LogUtils.makeLogTag(MediaFileListFragment.class);
|
||||
|
||||
public static final String MEDIA_TYPE = "mediaType";
|
||||
|
@ -80,15 +74,15 @@ public class MediaFileListFragment extends Fragment {
|
|||
String mediaType = Files.Media.MUSIC;
|
||||
String parentDirectory = null;
|
||||
int playlistId = PlaylistType.MUSIC_PLAYLISTID; // this is the ID of the music player
|
||||
private MediaFileListAdapter adapter = null;
|
||||
// private MediaFileListAdapter adapter = null;
|
||||
boolean browseRootAlready = false;
|
||||
|
||||
ArrayList<FileLocation> rootFileLocation = new ArrayList<FileLocation>();
|
||||
Queue<FileLocation> mediaQueueFileLocation = new LinkedList<>();
|
||||
|
||||
@InjectView(R.id.list) GridView folderGridView;
|
||||
@InjectView(R.id.swipe_refresh_layout) SwipeRefreshLayout swipeRefreshLayout;
|
||||
@InjectView(android.R.id.empty) TextView emptyView;
|
||||
// @InjectView(R.id.list) GridView folderGridView;
|
||||
// @InjectView(R.id.swipe_refresh_layout) SwipeRefreshLayout swipeRefreshLayout;
|
||||
// @InjectView(android.R.id.empty) TextView emptyView;
|
||||
|
||||
public static MediaFileListFragment newInstance(final String media) {
|
||||
MediaFileListFragment fragment = new MediaFileListFragment();
|
||||
|
@ -103,7 +97,7 @@ public class MediaFileListFragment extends Fragment {
|
|||
super.onSaveInstanceState(outState);
|
||||
outState.putString(MEDIA_TYPE, mediaType);
|
||||
try {
|
||||
outState.putParcelableArrayList(PATH_CONTENTS, (ArrayList<FileLocation>)adapter.getFileItemList());
|
||||
outState.putParcelableArrayList(PATH_CONTENTS, (ArrayList<FileLocation>) ((MediaFileListAdapter) getAdapter()).getFileItemList());
|
||||
} catch (NullPointerException npe) {
|
||||
// adapter is null probably nothing was save in bundle because the directory is empty
|
||||
// ignore this so that the empty message would display later on
|
||||
|
@ -112,8 +106,24 @@ public class MediaFileListFragment extends Fragment {
|
|||
outState.putBoolean(ROOT_VISITED, browseRootAlready);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AdapterView.OnItemClickListener createOnItemClickListener() {
|
||||
return new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
handleFileSelect(((MediaFileListAdapter) getAdapter()).getItem(position));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BaseAdapter createAdapter() {
|
||||
return new MediaFileListAdapter(getActivity(), R.layout.grid_item_file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View root = super.onCreateView(inflater, container, savedInstanceState);
|
||||
Bundle args = getArguments();
|
||||
if (args != null) {
|
||||
mediaType = args.getString(MEDIA_TYPE, Files.Media.MUSIC);
|
||||
|
@ -123,11 +133,8 @@ public class MediaFileListFragment extends Fragment {
|
|||
playlistId = PlaylistType.PICTURE_PLAYLISTID;
|
||||
}
|
||||
}
|
||||
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_generic_media_list, container, false);
|
||||
ButterKnife.inject(this, root);
|
||||
|
||||
hostManager = HostManager.getInstance(getActivity());
|
||||
swipeRefreshLayout.setEnabled(false);
|
||||
|
||||
emptyView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
@ -135,18 +142,7 @@ public class MediaFileListFragment extends Fragment {
|
|||
browseSources();
|
||||
}
|
||||
});
|
||||
folderGridView.setEmptyView(emptyView);
|
||||
folderGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
handleFileSelect(adapter.getItem(position));
|
||||
}
|
||||
});
|
||||
|
||||
if (adapter == null) {
|
||||
adapter = new MediaFileListAdapter(getActivity(), R.layout.grid_item_file);
|
||||
}
|
||||
folderGridView.setAdapter(adapter);
|
||||
if (savedInstanceState != null) {
|
||||
mediaType = savedInstanceState.getString(MEDIA_TYPE);
|
||||
//currentPath = savedInstanceState.getString(CURRENT_PATH);
|
||||
|
@ -158,7 +154,7 @@ public class MediaFileListFragment extends Fragment {
|
|||
ArrayList<FileLocation> list = savedInstanceState.getParcelableArrayList(PATH_CONTENTS);
|
||||
rootFileLocation = savedInstanceState.getParcelableArrayList(ROOT_PATH_CONTENTS);
|
||||
browseRootAlready = savedInstanceState.getBoolean(ROOT_VISITED);
|
||||
adapter.setFilelistItems(list);
|
||||
((MediaFileListAdapter) getAdapter()).setFilelistItems(list);
|
||||
}
|
||||
else {
|
||||
browseSources();
|
||||
|
@ -187,13 +183,13 @@ public class MediaFileListFragment extends Fragment {
|
|||
|
||||
public void onBackPressed() {
|
||||
// Emulate a click on ..
|
||||
handleFileSelect(adapter.getItem(0));
|
||||
handleFileSelect(((MediaFileListAdapter) getAdapter()).getItem(0));
|
||||
}
|
||||
|
||||
public boolean atRootDirectory() {
|
||||
if (adapter.getCount() == 0)
|
||||
if (getAdapter().getCount() == 0)
|
||||
return true;
|
||||
FileLocation fl = adapter.getItem(0);
|
||||
FileLocation fl = ((MediaFileListAdapter) getAdapter()).getItem(0);
|
||||
if (fl == null)
|
||||
return true;
|
||||
else
|
||||
|
@ -224,7 +220,7 @@ public class MediaFileListFragment extends Fragment {
|
|||
|
||||
browseRootAlready = true;
|
||||
emptyView.setText(getString(R.string.source_empty));
|
||||
adapter.setFilelistItems(rootFileLocation);
|
||||
((MediaFileListAdapter) getAdapter()).setFilelistItems(rootFileLocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -320,7 +316,7 @@ public class MediaFileListFragment extends Fragment {
|
|||
for (ListType.ItemFile i : result) {
|
||||
flList.add(FileLocation.newInstanceFromItemFile(getActivity(), i));
|
||||
}
|
||||
adapter.setFilelistItems(flList);
|
||||
((MediaFileListAdapter) getAdapter()).setFilelistItems(flList);
|
||||
browseRootAlready = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ import org.xbmc.kore.utils.Utils;
|
|||
/**
|
||||
* Fragment that presents the movie list
|
||||
*/
|
||||
public class MovieListFragment extends AbstractListFragment {
|
||||
public class MovieListFragment extends AbstractCursorListFragment {
|
||||
private static final String TAG = LogUtils.makeLogTag(MovieListFragment.class);
|
||||
|
||||
public interface OnMovieSelectedListener {
|
||||
|
|
|
@ -50,7 +50,7 @@ import org.xbmc.kore.utils.Utils;
|
|||
/**
|
||||
* Fragment that presents the artists list
|
||||
*/
|
||||
public class MusicVideoListFragment extends AbstractListFragment {
|
||||
public class MusicVideoListFragment extends AbstractCursorListFragment {
|
||||
private static final String TAG = LogUtils.makeLogTag(MusicVideoListFragment.class);
|
||||
|
||||
public interface OnMusicVideoSelectedListener {
|
||||
|
|
|
@ -53,7 +53,7 @@ import org.xbmc.kore.utils.Utils;
|
|||
/**
|
||||
* Fragment that presents the tv show list
|
||||
*/
|
||||
public class TVShowListFragment extends AbstractListFragment {
|
||||
public class TVShowListFragment extends AbstractCursorListFragment {
|
||||
private static final String TAG = LogUtils.makeLogTag(TVShowListFragment.class);
|
||||
|
||||
public interface OnTVShowSelectedListener {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?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">
|
||||
<item android:id="@+id/action_refresh"
|
||||
android:title="@string/refresh"
|
||||
app:showAsAction="never"/>
|
||||
</menu>
|
|
@ -20,7 +20,4 @@
|
|||
<item android:id="@+id/action_multi_single_columns"
|
||||
android:title="@string/single_column"
|
||||
app:showAsAction="never"/>
|
||||
<item android:id="@+id/action_refresh"
|
||||
android:title="@string/refresh"
|
||||
app:showAsAction="never"/>
|
||||
</menu>
|
||||
|
|
Loading…
Reference in New Issue