Changeset View
Changeset View
Standalone View
Standalone View
src/it/reyboz/bustorino/fragments/ResultListFragment.java
/* | /* | ||||
BusTO - Fragments components | BusTO - Fragments components | ||||
Copyright (C) 2016 Fabio Mazza | Copyright (C) 2016 Fabio Mazza | ||||
This program is free software: you can redistribute it and/or modify | This program is free software: you can redistribute it and/or modify | ||||
it under the terms of the GNU General Public License as published by | it under the terms of the GNU General Public License as published by | ||||
the Free Software Foundation, either version 3 of the License, or | the Free Software Foundation, either version 3 of the License, or | ||||
(at your option) any later version. | (at your option) any later version. | ||||
This program is distributed in the hope that it will be useful, | This program is distributed in the hope that it will be useful, | ||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
GNU General Public License for more details. | GNU General Public License for more details. | ||||
You should have received a copy of the GNU General Public License | You should have received a copy of the GNU General Public License | ||||
along with this program. If not, see <http://www.gnu.org/licenses/>. | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
package it.reyboz.bustorino.fragments; | package it.reyboz.bustorino.fragments; | ||||
import android.content.Context; | import android.content.Context; | ||||
import android.os.Bundle; | import android.database.sqlite.SQLiteDatabase; | ||||
import android.os.Parcelable; | import android.os.Bundle; | ||||
import android.support.annotation.Nullable; | import android.os.Parcelable; | ||||
import android.support.v4.app.Fragment; | import android.support.annotation.Nullable; | ||||
import android.support.v4.widget.SwipeRefreshLayout; | import android.support.v4.app.Fragment; | ||||
import android.util.Log; | import android.support.v4.widget.SwipeRefreshLayout; | ||||
import android.view.LayoutInflater; | import android.util.Log; | ||||
import android.view.View; | import android.view.LayoutInflater; | ||||
import android.view.ViewGroup; | import android.view.View; | ||||
import android.view.ViewGroup; | |||||
import android.widget.*; | |||||
import android.support.design.widget.FloatingActionButton; | import android.widget.*; | ||||
import android.support.design.widget.FloatingActionButton; | |||||
import it.reyboz.bustorino.R; | |||||
import it.reyboz.bustorino.backend.FiveTNormalizer; | import it.reyboz.bustorino.R; | ||||
import it.reyboz.bustorino.backend.Palina; | import it.reyboz.bustorino.backend.FiveTNormalizer; | ||||
import it.reyboz.bustorino.backend.Route; | import it.reyboz.bustorino.backend.Palina; | ||||
import it.reyboz.bustorino.backend.Stop; | import it.reyboz.bustorino.backend.Route; | ||||
import it.reyboz.bustorino.backend.Stop; | |||||
/** | import it.reyboz.bustorino.middleware.UserDB; | ||||
* This is a generalized fragment that can be used both for | |||||
* | /** | ||||
* | * This is a generalized fragment that can be used both for | ||||
*/ | * | ||||
public class ResultListFragment extends Fragment{ | * | ||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER | */ | ||||
static final String LIST_TYPE = "list-type"; | public class ResultListFragment extends Fragment{ | ||||
private static final String STOP_TITLE = "messageExtra"; | // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER | ||||
protected static final String LIST_STATE = "list_state"; | static final String LIST_TYPE = "list-type"; | ||||
private static final String STOP_TITLE = "messageExtra"; | |||||
protected static final String LIST_STATE = "list_state"; | |||||
private static final String MESSAGE_TEXT_VIEW = "message_text_view"; | |||||
private FragmentKind adapterKind; | |||||
private static final String MESSAGE_TEXT_VIEW = "message_text_view"; | |||||
private boolean adapterSet = false; | private FragmentKind adapterKind; | ||||
protected FragmentListener mListener; | |||||
private TextView messageTextView; | private boolean adapterSet = false; | ||||
protected FragmentListener mListener; | |||||
private FloatingActionButton fabutton; | private TextView messageTextView; | ||||
private ListView resultsListView; | private ImageButton addToFavorites; | ||||
private ListAdapter mListAdapter = null; | |||||
boolean listShown; | private FloatingActionButton fabutton; | ||||
private Parcelable mListInstanceState = null; | private ListView resultsListView; | ||||
private ListAdapter mListAdapter = null; | |||||
public ResultListFragment() { | boolean listShown; | ||||
// Required empty public constructor | private Parcelable mListInstanceState = null; | ||||
} | |||||
public ResultListFragment() { | |||||
public ListView getResultsListView() { | // Required empty public constructor | ||||
return resultsListView; | } | ||||
} | |||||
public ListView getResultsListView() { | |||||
/** | return resultsListView; | ||||
* Use this factory method to create a new instance of | } | ||||
* this fragment using the provided parameters. | |||||
* | /** | ||||
* @param listType whether the list is used for STOPS or LINES (Orari) | * Use this factory method to create a new instance of | ||||
* @return A new instance of fragment ResultListFragment. | * this fragment using the provided parameters. | ||||
*/ | * | ||||
public static ResultListFragment newInstance(FragmentKind listType, String eventualStopTitle) { | * @param listType whether the list is used for STOPS or LINES (Orari) | ||||
ResultListFragment fragment = new ResultListFragment(); | * @return A new instance of fragment ResultListFragment. | ||||
Bundle args = new Bundle(); | */ | ||||
args.putSerializable(LIST_TYPE, listType); | public static ResultListFragment newInstance(FragmentKind listType, String eventualStopTitle) { | ||||
if (eventualStopTitle != null) { | ResultListFragment fragment = new ResultListFragment(); | ||||
args.putString(STOP_TITLE, eventualStopTitle); | Bundle args = new Bundle(); | ||||
} | args.putSerializable(LIST_TYPE, listType); | ||||
fragment.setArguments(args); | if (eventualStopTitle != null) { | ||||
return fragment; | args.putString(STOP_TITLE, eventualStopTitle); | ||||
} | } | ||||
fragment.setArguments(args); | |||||
public static ResultListFragment newInstance(FragmentKind listType) { | return fragment; | ||||
return newInstance(listType, null); | } | ||||
} | |||||
public static ResultListFragment newInstance(FragmentKind listType) { | |||||
@Override | return newInstance(listType, null); | ||||
public void onCreate(Bundle savedInstanceState) { | } | ||||
super.onCreate(savedInstanceState); | |||||
if (getArguments() != null) { | @Override | ||||
adapterKind = (FragmentKind) getArguments().getSerializable(LIST_TYPE); | public void onCreate(Bundle savedInstanceState) { | ||||
} | super.onCreate(savedInstanceState); | ||||
} | if (getArguments() != null) { | ||||
adapterKind = (FragmentKind) getArguments().getSerializable(LIST_TYPE); | |||||
@Override | } | ||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, | } | ||||
Bundle savedInstanceState) { | |||||
View root = inflater.inflate(R.layout.fragment_list_view, container, false); | /** | ||||
messageTextView = (TextView) root.findViewById(R.id.messageTextView); | * Check if the last Bus Stop is in the favorites | ||||
* @return | |||||
if (adapterKind != null) { | */ | ||||
resultsListView = (ListView) root.findViewById(R.id.resultsListView); | public boolean isStopInFavorites(String busStopId) { | ||||
switch (adapterKind) { | boolean found = false; | ||||
case STOPS: | |||||
resultsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { | // no stop no party | ||||
if(busStopId != null) { | |||||
@Override | SQLiteDatabase userDB = new UserDB(getContext()).getReadableDatabase(); | ||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { | found = UserDB.isStopInFavorites(userDB, busStopId); | ||||
/* | } | ||||
* Casting because of Javamerda | |||||
* @url http://stackoverflow.com/questions/30549485/androids-list-view-parameterized-type-in-adapterview-onitemclicklistener | return found; | ||||
*/ | } | ||||
Stop busStop = (Stop) parent.getItemAtPosition(position); | |||||
mListener.createFragmentForStop(busStop.ID); | @Override | ||||
} | public View onCreateView(LayoutInflater inflater, ViewGroup container, | ||||
}); | Bundle savedInstanceState) { | ||||
View root = inflater.inflate(R.layout.fragment_list_view, container, false); | |||||
//set the textviewMessage | messageTextView = (TextView) root.findViewById(R.id.messageTextView); | ||||
setTextViewMessage(getString(R.string.results)); | addToFavorites = (ImageButton) root.findViewById(R.id.addToFavorites); | ||||
break; | if (adapterKind != null) { | ||||
case ARRIVALS: | resultsListView = (ListView) root.findViewById(R.id.resultsListView); | ||||
resultsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { | switch (adapterKind) { | ||||
@Override | case STOPS: | ||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { | resultsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { | ||||
String routeName; | |||||
@Override | |||||
Route r = (Route) parent.getItemAtPosition(position); | public void onItemClick(AdapterView<?> parent, View view, int position, long id) { | ||||
routeName = FiveTNormalizer.routeInternalToDisplay(r.getNameForDisplay()); | /* | ||||
if (routeName == null) { | * Casting because of Javamerda | ||||
routeName = r.getNameForDisplay(); | * @url http://stackoverflow.com/questions/30549485/androids-list-view-parameterized-type-in-adapterview-onitemclicklistener | ||||
} | */ | ||||
if (r.destinazione == null || r.destinazione.length() == 0) { | Stop busStop = (Stop) parent.getItemAtPosition(position); | ||||
Toast.makeText(getContext(), | mListener.createFragmentForStop(busStop.ID); | ||||
getString(R.string.route_towards_unknown, routeName), Toast.LENGTH_SHORT).show(); | } | ||||
} else { | }); | ||||
Toast.makeText(getContext(), | |||||
getString(R.string.route_towards_destination, routeName, r.destinazione), Toast.LENGTH_SHORT).show(); | //set the textviewMessage | ||||
} | setTextViewMessage(getString(R.string.results)); | ||||
} | break; | ||||
}); | case ARRIVALS: | ||||
String displayName = getArguments().getString(STOP_TITLE); | resultsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { | ||||
setTextViewMessage(String.format( | @Override | ||||
getString(R.string.passages), displayName)); | public void onItemClick(AdapterView<?> parent, View view, int position, long id) { | ||||
break; | String routeName; | ||||
default: | |||||
throw new IllegalStateException("Argument passed was not of a supported type"); | Route r = (Route) parent.getItemAtPosition(position); | ||||
} | routeName = FiveTNormalizer.routeInternalToDisplay(r.getNameForDisplay()); | ||||
if (routeName == null) { | |||||
String probablemessage = getArguments().getString(MESSAGE_TEXT_VIEW); | routeName = r.getNameForDisplay(); | ||||
if (probablemessage != null) { | } | ||||
//Log.d("BusTO fragment " + this.getTag(), "We have a possible message here in the savedInstaceState: " + probablemessage); | if (r.destinazione == null || r.destinazione.length() == 0) { | ||||
messageTextView.setText(probablemessage); | Toast.makeText(getContext(), | ||||
messageTextView.setVisibility(View.VISIBLE); | getString(R.string.route_towards_unknown, routeName), Toast.LENGTH_SHORT).show(); | ||||
} | } else { | ||||
Toast.makeText(getContext(), | |||||
} else | getString(R.string.route_towards_destination, routeName, r.destinazione), Toast.LENGTH_SHORT).show(); | ||||
Log.d(getString(R.string.list_fragment_debug), "No content root for fragment"); | } | ||||
return root; | } | ||||
} | }); | ||||
String displayName = getArguments().getString(STOP_TITLE); | |||||
public boolean isFragmentForTheSameStop(Palina p) { | setTextViewMessage(String.format( | ||||
return adapterKind.equals(FragmentKind.ARRIVALS) && getTag().equals(getFragmentTag(p)); | getString(R.string.passages), displayName)); | ||||
} | break; | ||||
default: | |||||
public static String getFragmentTag(Palina p) { | throw new IllegalStateException("Argument passed was not of a supported type"); | ||||
return p.ID; | } | ||||
} | |||||
String probablemessage = getArguments().getString(MESSAGE_TEXT_VIEW); | |||||
if (probablemessage != null) { | |||||
@Override | //Log.d("BusTO fragment " + this.getTag(), "We have a possible message here in the savedInstaceState: " + probablemessage); | ||||
public void onResume() { | messageTextView.setText(probablemessage); | ||||
super.onResume(); | messageTextView.setVisibility(View.VISIBLE); | ||||
//Log.d(getString(R.string.list_fragment_debug),"Fragment restored, saved listAdapter is "+(mListAdapter)); | } | ||||
if (mListAdapter != null) { | |||||
} else | |||||
ListAdapter adapter = mListAdapter; | Log.d(getString(R.string.list_fragment_debug), "No content root for fragment"); | ||||
mListAdapter = null; | return root; | ||||
setListAdapter(adapter); | } | ||||
} | |||||
if (mListInstanceState != null) { | public boolean isFragmentForTheSameStop(Palina p) { | ||||
Log.d("resultsListView", "trying to restore instance state"); | return adapterKind.equals(FragmentKind.ARRIVALS) && getTag().equals(getFragmentTag(p)); | ||||
resultsListView.onRestoreInstanceState(mListInstanceState); | } | ||||
} | |||||
switch (adapterKind) { | public static String getFragmentTag(Palina p) { | ||||
case ARRIVALS: | return p.ID; | ||||
resultsListView.setOnScrollListener(new CommonScrollListener(mListener, true)); | } | ||||
fabutton.show(); | |||||
break; | |||||
case STOPS: | @Override | ||||
resultsListView.setOnScrollListener(new CommonScrollListener(mListener, false)); | public void onResume() { | ||||
break; | super.onResume(); | ||||
default: | //Log.d(getString(R.string.list_fragment_debug),"Fragment restored, saved listAdapter is "+(mListAdapter)); | ||||
//NONE | if (mListAdapter != null) { | ||||
} | |||||
mListener.readyGUIfor(adapterKind); | ListAdapter adapter = mListAdapter; | ||||
mListAdapter = null; | |||||
} | setListAdapter(adapter); | ||||
} | |||||
@Override | if (mListInstanceState != null) { | ||||
public void onPause() { | Log.d("resultsListView", "trying to restore instance state"); | ||||
if (adapterKind.equals(FragmentKind.ARRIVALS)) { | resultsListView.onRestoreInstanceState(mListInstanceState); | ||||
SwipeRefreshLayout reflay = (SwipeRefreshLayout) getActivity().findViewById(R.id.listRefreshLayout); | } | ||||
reflay.setEnabled(false); | switch (adapterKind) { | ||||
Log.d("BusTO Fragment " + this.getTag(), "RefreshLayout disabled"); | case ARRIVALS: | ||||
} | resultsListView.setOnScrollListener(new CommonScrollListener(mListener, true)); | ||||
super.onPause(); | fabutton.show(); | ||||
} | break; | ||||
case STOPS: | |||||
@Override | resultsListView.setOnScrollListener(new CommonScrollListener(mListener, false)); | ||||
public void onAttach(Context context) { | break; | ||||
super.onAttach(context); | default: | ||||
if (context instanceof FragmentListener) { | //NONE | ||||
mListener = (FragmentListener) context; | } | ||||
fabutton = (FloatingActionButton) getActivity().findViewById(R.id.floatingActionButton); | mListener.readyGUIfor(adapterKind); | ||||
} else { | |||||
throw new RuntimeException(context.toString() | } | ||||
+ " must implement ResultFragmentListener"); | |||||
} | @Override | ||||
public void onPause() { | |||||
} | if (adapterKind.equals(FragmentKind.ARRIVALS)) { | ||||
SwipeRefreshLayout reflay = (SwipeRefreshLayout) getActivity().findViewById(R.id.listRefreshLayout); | |||||
reflay.setEnabled(false); | |||||
@Override | Log.d("BusTO Fragment " + this.getTag(), "RefreshLayout disabled"); | ||||
public void onDetach() { | } | ||||
mListener = null; | super.onPause(); | ||||
if (fabutton != null) | } | ||||
fabutton.show(); | |||||
super.onDetach(); | @Override | ||||
} | public void onAttach(Context context) { | ||||
super.onAttach(context); | |||||
if (context instanceof FragmentListener) { | |||||
@Override | mListener = (FragmentListener) context; | ||||
public void onDestroyView() { | fabutton = (FloatingActionButton) getActivity().findViewById(R.id.floatingActionButton); | ||||
resultsListView = null; | } else { | ||||
//Log.d(getString(R.string.list_fragment_debug), "called onDestroyView"); | throw new RuntimeException(context.toString() | ||||
getArguments().putString(MESSAGE_TEXT_VIEW, messageTextView.getText().toString()); | + " must implement ResultFragmentListener"); | ||||
super.onDestroyView(); | } | ||||
} | |||||
} | |||||
@Override | |||||
public void onViewStateRestored(@Nullable Bundle savedInstanceState) { | @Override | ||||
super.onViewStateRestored(savedInstanceState); | public void onDetach() { | ||||
Log.d("ResultListFragment", "onViewStateRestored"); | mListener = null; | ||||
if (savedInstanceState != null) { | if (fabutton != null) | ||||
mListInstanceState = savedInstanceState.getParcelable(LIST_STATE); | fabutton.show(); | ||||
Log.d("ResultListFragment", "listInstanceStatePresent :" + mListInstanceState); | super.onDetach(); | ||||
} | } | ||||
} | |||||
public void setListAdapter(ListAdapter adapter) { | @Override | ||||
boolean hadAdapter = mListAdapter != null; | public void onDestroyView() { | ||||
mListAdapter = adapter; | resultsListView = null; | ||||
if (resultsListView != null) { | //Log.d(getString(R.string.list_fragment_debug), "called onDestroyView"); | ||||
resultsListView.setAdapter(adapter); | getArguments().putString(MESSAGE_TEXT_VIEW, messageTextView.getText().toString()); | ||||
resultsListView.setVisibility(View.VISIBLE); | super.onDestroyView(); | ||||
} | } | ||||
} | |||||
/** | @Override | ||||
* Set the message textView | public void onViewStateRestored(@Nullable Bundle savedInstanceState) { | ||||
* @param message the whole message to write in the textView | super.onViewStateRestored(savedInstanceState); | ||||
*/ | Log.d("ResultListFragment", "onViewStateRestored"); | ||||
public void setTextViewMessage(String message) { | if (savedInstanceState != null) { | ||||
messageTextView.setText(message); | mListInstanceState = savedInstanceState.getParcelable(LIST_STATE); | ||||
switch (adapterKind) { | Log.d("ResultListFragment", "listInstanceStatePresent :" + mListInstanceState); | ||||
case ARRIVALS: | } | ||||
messageTextView.setClickable(true); | } | ||||
messageTextView.setOnClickListener(new View.OnClickListener() { | |||||
@Override | public void setListAdapter(ListAdapter adapter) { | ||||
public void onClick(View v) { | boolean hadAdapter = mListAdapter != null; | ||||
// add/remove the stop in the favorites | mListAdapter = adapter; | ||||
mListener.toggleLastStopToFavorites(); | if (resultsListView != null) { | ||||
} | resultsListView.setAdapter(adapter); | ||||
}); | resultsListView.setVisibility(View.VISIBLE); | ||||
break; | } | ||||
case STOPS: | } | ||||
messageTextView.setClickable(false); | |||||
break; | /** | ||||
} | * Set the message textView | ||||
* @param message the whole message to write in the textView | |||||
messageTextView.setVisibility(View.VISIBLE); | */ | ||||
} | public void setTextViewMessage(String message) { | ||||
} | messageTextView.setText(message); | ||||
switch (adapterKind) { | |||||
case ARRIVALS: | |||||
addToFavorites.setClickable(true); | |||||
addToFavorites.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) { | |||||
// add/remove the stop in the favorites | |||||
mListener.toggleLastStopToFavorites(); | |||||
} | |||||
}); | |||||
break; | |||||
case STOPS: | |||||
addToFavorites.setClickable(false); | |||||
break; | |||||
} | |||||
messageTextView.setVisibility(View.VISIBLE); | |||||
} | |||||
} | |||||
No newline at end of file |
Public contents are in Creative Commons Attribution-ShareAlike 4.0 (CC-BY-SA) or GNU Free Documentation License (at your option) unless otherwise noted. · Contact / Register