/* ownCloud Android client application
* Copyright (C) 2012 Bartek Przybylski
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
package com.owncloud.android.ui.fragment;
import java.util.ArrayList;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.ListAdapter;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragment;
import com.owncloud.android.R;
import com.owncloud.android.lib.common.utils.Log_OC;
import third_parties.in.srain.cube.GridViewWithHeaderAndFooter;
import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
/**
* TODO extending SherlockListFragment instead of SherlockFragment
*/
public class ExtendedListFragment extends SherlockFragment
implements OnItemClickListener, OnEnforceableRefreshListener {
private static final String TAG = ExtendedListFragment.class.getSimpleName();
private static final String KEY_SAVED_LIST_POSITION = "SAVED_LIST_POSITION";
private static final String KEY_INDEXES = "INDEXES";
private static final String KEY_FIRST_POSITIONS= "FIRST_POSITIONS";
private static final String KEY_TOPS = "TOPS";
private static final String KEY_HEIGHT_CELL = "HEIGHT_CELL";
private static final String KEY_EMPTY_LIST_MESSAGE = "EMPTY_LIST_MESSAGE";
private SwipeRefreshLayout mRefreshLayout;
private SwipeRefreshLayout mRefreshEmptyLayout;
private TextView mEmptyListMessage;
// Save the state of the scroll in browsing
private ArrayList mIndexes;
private ArrayList mFirstPositions;
private ArrayList mTops;
private int mHeightCell = 0;
private OnEnforceableRefreshListener mOnRefreshListener = null;
protected GridViewWithHeaderAndFooter imageView;
public void setListAdapter(ListAdapter listAdapter) {
imageView.setAdapter(listAdapter);
imageView.invalidate();
}
public GridView getGridView() {
return imageView;
}
public void setFooterView(View footer) {
imageView.addFooterView(footer, null, false);
imageView.invalidate();
}
public void removeFooterView(View footer) {
imageView.removeFooterView(footer);
imageView.invalidate();
}
public int getFooterViewCount() {
return imageView.getFooterViewCount();
}
protected void switchImageView(){
imageView.setNumColumns(GridView.AUTO_FIT);
imageView.invalidateRowHeight(); // Force to recalculate mRowHeight of imageView
imageView.invalidate();
}
protected void switchFileView(){
imageView.setNumColumns(1);
imageView.invalidate();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log_OC.e(TAG, "onCreateView");
View v = inflater.inflate(R.layout.list_fragment, null);
imageView = (GridViewWithHeaderAndFooter)(v.findViewById(R.id.list_root));
imageView.setOnItemClickListener(this);
if (savedInstanceState != null) {
int referencePosition = savedInstanceState.getInt(KEY_SAVED_LIST_POSITION);
setReferencePosition(referencePosition);
}
// Pull down refresh
mRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_refresh_files);
mRefreshEmptyLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_refresh_files_emptyView);
mEmptyListMessage = (TextView) v.findViewById(R.id.empty_list_view);
onCreateSwipeToRefresh(mRefreshLayout);
onCreateSwipeToRefresh(mRefreshEmptyLayout);
imageView.setEmptyView(mRefreshEmptyLayout);
return v;
}
/**
* {@inheritDoc}
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
mIndexes = savedInstanceState.getIntegerArrayList(KEY_INDEXES);
mFirstPositions = savedInstanceState.getIntegerArrayList(KEY_FIRST_POSITIONS);
mTops = savedInstanceState.getIntegerArrayList(KEY_TOPS);
mHeightCell = savedInstanceState.getInt(KEY_HEIGHT_CELL);
setMessageForEmptyList(savedInstanceState.getString(KEY_EMPTY_LIST_MESSAGE));
} else {
mIndexes = new ArrayList();
mFirstPositions = new ArrayList();
mTops = new ArrayList();
mHeightCell = 0;
}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log_OC.e(TAG, "onSaveInstanceState()");
savedInstanceState.putInt(KEY_SAVED_LIST_POSITION, getReferencePosition());
savedInstanceState.putIntegerArrayList(KEY_INDEXES, mIndexes);
savedInstanceState.putIntegerArrayList(KEY_FIRST_POSITIONS, mFirstPositions);
savedInstanceState.putIntegerArrayList(KEY_TOPS, mTops);
savedInstanceState.putInt(KEY_HEIGHT_CELL, mHeightCell);
savedInstanceState.putString(KEY_EMPTY_LIST_MESSAGE, getEmptyViewText());
}
/**
* Calculates the position of the item that will be used as a reference to
* reposition the visible items in the list when the device is turned to
* other position.
*
* THe current policy is take as a reference the visible item in the center
* of the screen.
*
* @return The position in the list of the visible item in the center of the
* screen.
*/
protected int getReferencePosition() {
if (imageView != null) {
return (imageView.getFirstVisiblePosition() + imageView.getLastVisiblePosition()) / 2;
} else {
return 0;
}
}
/**
* Sets the visible part of the list from the reference position.
*
* @param position Reference position previously returned by
* {@link LocalFileListFragment#getReferencePosition()}
*/
protected void setReferencePosition(int position) {
if (imageView != null) {
imageView.setSelection(position);
}
}
/*
* Restore index and position
*/
protected void restoreIndexAndTopPosition() {
if (mIndexes.size() > 0) {
// needs to be checked; not every browse-up had a browse-down before
int index = mIndexes.remove(mIndexes.size() - 1);
int firstPosition = mFirstPositions.remove(mFirstPositions.size() -1);
int top = mTops.remove(mTops.size() - 1);
imageView.smoothScrollToPosition(firstPosition);
// Move the scroll if the selection is not visible
int indexPosition = mHeightCell*index;
int height = imageView.getHeight();
if (indexPosition > height) {
imageView.smoothScrollToPosition(index);
}
}
}
/*
* Save index and top position
*/
protected void saveIndexAndTopPosition(int index) {
mIndexes.add(index);
int firstPosition = imageView.getFirstVisiblePosition();
mFirstPositions.add(firstPosition);
View view = imageView.getChildAt(0);
int top = (view == null) ? 0 : view.getTop() ;
mTops.add(top);
// Save the height of a cell
mHeightCell = (view == null || mHeightCell != 0) ? mHeightCell : view.getHeight();
}
@Override
public void onItemClick (AdapterView> parent, View view, int position, long id) {
// to be @overriden
}
@Override
public void onRefresh() {
// to be @overriden
mRefreshLayout.setRefreshing(false);
mRefreshEmptyLayout.setRefreshing(false);
if (mOnRefreshListener != null) {
mOnRefreshListener.onRefresh();
}
}
public void setOnRefreshListener(OnEnforceableRefreshListener listener) {
mOnRefreshListener = listener;
}
/**
* Enables swipe gesture
*/
public void enableSwipe() {
mRefreshLayout.setEnabled(true);
}
/**
* Disables swipe gesture. It prevents manual gestures but keeps the option you show
* refreshing programmatically.
*/
public void disableSwipe() {
mRefreshLayout.setEnabled(false);
}
/**
* It shows the SwipeRefreshLayout progress
*/
public void showSwipeProgress() {
mRefreshLayout.setRefreshing(true);
}
/**
* It shows the SwipeRefreshLayout progress
*/
public void hideSwipeProgress() {
mRefreshLayout.setRefreshing(false);
}
/**
* Set message for empty list view
*/
public void setMessageForEmptyList(String message) {
if (mEmptyListMessage != null) {
mEmptyListMessage.setText(message);
}
}
/**
* Get the text of EmptyListMessage TextView
*
* @return String
*/
public String getEmptyViewText() {
return (mEmptyListMessage != null) ? mEmptyListMessage.getText().toString() : "";
}
private void onCreateSwipeToRefresh(SwipeRefreshLayout refreshLayout) {
// Colors in animations: background
refreshLayout.setColorScheme(R.color.background_color, R.color.background_color, R.color.background_color,
R.color.background_color);
refreshLayout.setOnRefreshListener(this);
}
@Override
public void onRefresh(boolean ignoreETag) {
mRefreshLayout.setRefreshing(false);
mRefreshEmptyLayout.setRefreshing(false);
if (mOnRefreshListener != null) {
mOnRefreshListener.onRefresh(ignoreETag);
}
}
}