【发布时间】:2015-06-25 21:53:14
【问题描述】:
我正在开发一个允许查看曲棍球比赛结果的 Android 应用程序。
我使用ViewPager 和自定义FragmentPagerAdapter 来显示三个片段,以及NavigationDrawer 和ExpandableListView,用于显示冠军。
当我点击ExpandableListViewchildss时,我想用所选冠军的数据更新三个片段。
我在NavigationDrawer 中设置了一个OnchildClickListener,在那里我实例化了一个FragmentManager 并调用了replace() 方法。但它只是返回一个空白屏幕。
我在每个论坛都搜索并尝试了不同的解决方案,但没有一个有效
当我使用ft.add() 而不是ft.replace() 并使用SwipeRefreshLayout 刷新页面时,我得到了正确的结果,但我想在不手动刷新页面的情况下得到它。
我还尝试将FragmentPagerAdapter 替换为FragmentStatePagerAdapter,但没有任何改变。
NavigationDrawerFragment
package com.dcdeveloper.fihresults;
public class NavigationDrawerFragment extends Fragment {
/**
* Immagazzina lo stato della posizione dell'elemento selezionato.
*/
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
/**
* Per the design guidelines, you should show the drawer on launch until the user manually
* expands it. This shared preference tracks this.
*/
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
/**
* A pointer to the current callbacks instance (the Activity).
*/
private NavigationDrawerCallbacks mCallbacks;
/**
* Helper component that ties the action bar to the navigation drawer.
*/
private ActionBarDrawerToggle mDrawerToggle;
/**
* Memorizza l'istanza del DrawerLayout
*/
private DrawerLayout mDrawerLayout;
/**View di questa barra di navigazione*/
private View mFragmentContainerView;
/**Posizione dell'elemento selezionato all'interno della lista*/
private int mCurrentSelectedPosition = 0;
private boolean mFromSavedInstanceState;
/**Boolean che indica se l'utente è venuto a conoscenza dell'utilizzo della barra laterale.Utilizzato per accessibilità.*/
private boolean mUserLearnedDrawer;
private ActionBarDrawerToggle actionBarDrawerToggle;
/**Lista con elementi espandibili,contiene i dati relativi ai campionati*/
ExpandableListView expListView;
/**adapter per inserire i dati nella ExpandableListView*/
MyExpandableListAdapter expandableListAdapter;
/*ArrayList dei titoli dei campionati*/
List<String> listDataHeader;
/**Hashmap contenente i dati relativi ai campionati,collegati ai relativi titoli*/
HashMap<String, List<String>> listDataChild;
HashMap<Campionato,Integer>listaCampionati;
/**Stringa contenente l'url del WS a cui si effettueranno le richieste HTTP per ricevere i dati dei campionati*/
String wsURL;
/**ID del campionato,utilizzato per aggiornare le pagine una volta premuto l'elemento di un campionato nella lista*/
protected int key;
/**Memorizza il titolo dell'Activity,in modo da cambiare il titolo della MainActivity*/
CharSequence mDrawerTitle;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Read in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
// Select either the default item (0) or the last selected item.
selectItem(mCurrentSelectedPosition);
//Stringa contenente l'url del Web Service
wsURL = "http://fihresults.altervista.org/WebServiceFihResults/service.php";
//Prepara le intestazioni standard dei campionati
prepareHeaderData();
}
/**
* Metodo costruttore della view.Utilizza il layout predefinito del frammento.
* I dati inseriti all'interno del ListLayout vengono ricevuti dal server ed organizzati
* all' interno della lista.
*
*/
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
expListView = (ExpandableListView) inflater.inflate(
R.layout.fragment_navigation_campionati, container, false);
expListView .setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
mDrawerTitle= getActionBar().getTitle();
}
});
/**
* Definisce una nuova richiesta HTTP. Essa preleva i nomi ed i dati dei vari campionati,
* riempiendo degli ArrayList che saranno poi usati per creare l'ExpandableListView
*/
if(hasConnection(getActivity())) {
HTTPRequest http=new HTTPRequest() {
@Override
protected void onPostExecute(String result) {
//ArrayList di tutti i children che saranno inseriti nell'ExpandableListView
ArrayList<String>A1M=new ArrayList();
ArrayList<String>A1F=new ArrayList();
ArrayList<String>A2M=new ArrayList();
ArrayList<String>A2F=new ArrayList();
ArrayList<String>B=new ArrayList();
ArrayList<String>U21M=new ArrayList();
ArrayList<String>U19F=new ArrayList();
ArrayList<String>U17M=new ArrayList();
ArrayList<String>U16F=new ArrayList();
ArrayList<String>U14M=new ArrayList();
ArrayList<String>U14F=new ArrayList();
ArrayList<String>U12X=new ArrayList();
super.onPostExecute(result);
try {
//Formatta il risultato in un JSONArray
JSONArray dati = new JSONArray(result);
Log.i("INFO",result);
String categoria; //Categoria del campionato
String genere; //Genere (Maschile,Femminile,Misto)
String girone; //Girone del campionato
String idcampionato;
for(int i=0;i<dati.length();i++)
{
JSONObject jsonobject = dati.getJSONObject(i);
categoria=jsonobject.getString("Categoria");
genere= jsonobject.getString("Genere");
girone= jsonobject.getString("Girone");
idcampionato= jsonobject.getString("IDCampionato");
switch (categoria){
case "A1":
if(genere.equals("Maschile")) {
A1M.add(idcampionato+" Serie " + categoria + " " + genere + " " + girone);
}
else {
A1F.add(idcampionato+" Serie " + categoria + " " + genere + " " + girone);
}
break;
case "A2":
if(genere.equals("Maschile")) {
A2M.add(idcampionato+" Serie " +categoria + " " + genere + " " + girone);
}
else {
A2F.add(idcampionato+" Serie " +categoria + " " + genere + " " + girone);
}
break;
case "B":
B.add(idcampionato+" Serie " +categoria + " " + genere + " "+girone);
break;
case "UNDER 21":
U21M.add(categoria + " " + genere + " "+girone);
break;
case "UNDER 19":
U19F.add(categoria + " " + genere + " "+girone);
break;
case "UNDER 17":
U17M.add(categoria + " " + genere + " "+girone);
break;
case "UNDER 16":
U16F.add(categoria + " " + genere + " "+girone);
break;
case "UNDER 14":
if(genere.equals("Maschile")) {
U14M.add(categoria + " " + genere + " " + girone);
}
else {
U14F.add(categoria + " " + genere + " " + girone);
}
break;
case "UNDER 12":
U12X.add(categoria + " " + genere + " "+girone);
break;
}
setChildGroupData(A1M, A1F, A2M, A2F, B, U21M, U19F, U17M, U16F, U14M
, U14F, U12X);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected String doInBackground(String... params) {
return super.doInBackground(params);
}
};
//Effettua richiesta HTTP al WS
http.execute(wsURL, "0", "mostraCampionati");
//Crea un adapter per inserire gli ArrayList nell'ExpandableListView
Log.i("INFO", String.valueOf(listDataChild.size()));
expandableListAdapter = new MyExpandableListAdapter(getActivity().getBaseContext(), listDataHeader, listDataChild);
//Sets the adapter for ExpandableList
expListView.setAdapter(expandableListAdapter);
//Sets the OnClickListener for childrens of the list
expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
String child = (String) parent.getExpandableListAdapter().getChild(groupPosition, childPosition);
String[] parti = child.split(" ");
key = Integer.parseInt(parti[0]); //gets the key of tuple which is the first part of the string
//gets Fragment Manager
FragmentManager fragmentManager = getFragmentManager();
//starts the transaction
android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.viewpager, PagePartite.newInstance(key)); //first page
ft.replace(R.id.viewpager, PageClassifica.newInstance(key)); //second page
ft.replace(R.id.viewpager, PageStatistiche.newInstance(key));
ft.addToBackStack(null);
ft.commit();
mDrawerTitle = (child);
return true;
}
});
}
else
Toast.makeText(getActivity(),"Connessione Internet assente",Toast.LENGTH_LONG).show();
return expListView ;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (NavigationDrawerCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
}
}
@Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
/**
* Per the navigation drawer design guidelines, updates the action bar to show the global app
* 'context', rather than just what's in the current screen.
*/
private void showGlobalContextActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
}
private ActionBar getActionBar() {
return ((ActionBarActivity) getActivity()).getSupportActionBar();
}
/**
* Funzione che riempie l'HashMap ListDataChild con i dati ricevuti tramite richiesta HTTP.
* @param par ArrayList contenente i dati per ogni campionato
*/
protected void setChildGroupData(ArrayList<String> ... par){
//inserisce i dati dei Children e dei parent in un HashMap
listDataChild.put(listDataHeader.get(0), par[0]);
listDataChild.put(listDataHeader.get(1),par[1]);
listDataChild.put(listDataHeader.get(2),par[2]);
listDataChild.put(listDataHeader.get(3),par[3]);
listDataChild.put(listDataHeader.get(4),par[4]);
listDataChild.put(listDataHeader.get(5),par[5]);
listDataChild.put(listDataHeader.get(6),par[6]);
listDataChild.put(listDataHeader.get(7),par[7]);
listDataChild.put(listDataHeader.get(8),par[8]);
listDataChild.put(listDataHeader.get(9),par[9]);
listDataChild.put(listDataHeader.get(10),par[10]);
listDataChild.put(listDataHeader.get(11),par[11]);
}
/**
* Lista che inserisce i titoli dei campionati all'interno di una HashMap
*/
private void prepareHeaderData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
//Titoli delle sezioni
listDataHeader.add("Serie A1 Maschile");
listDataHeader.add("Serie A1 Femminile");
listDataHeader.add("Serie A2 Maschile");
listDataHeader.add("Serie A2 Femminile");
listDataHeader.add("Serie B Maschile");
listDataHeader.add("Under 21 Maschile");
listDataHeader.add("Under 19 Femminile");
listDataHeader.add("Under 17 Maschile");
listDataHeader.add("Under 16 Femminile");
listDataHeader.add("Under 14 Maschile");
listDataHeader.add("Under 14 Femminile");
listDataHeader.add("Under 12 Mista");
}
/**
* Callbacks interface that all activities using this fragment must implement.
*/
public static interface NavigationDrawerCallbacks {
/**
* Called when an item in the navigation drawer is selected.
*/
void onNavigationDrawerItemSelected(int position);
}
第一个片段
package com.dcdeveloper.fihresults;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
/**
* Fragment contenente le partite del campionato,disposte in giornate
* Use the {@link PagePartite#newInstance} factory method to
* create an instance of this fragment.
*/
// In this case, the fragment displays simple text based on the page
public class PagePartite extends Fragment implements AdapterView.OnItemSelectedListener{
/** View del frammento*/
protected View view;
private int mPage;
/**URL del WEB Service a cui effettuare richieste HTTP per ottenere i risultati delle partite*/
private String wsURL;
/**ID del campionato scelto*/
private static int idcampionato;
/**Layout che consente l'aggiornamento della pagina tramite swipe verticale*/
SwipeRefreshLayout mSwipeRefreshLayout;
/**Barra di progresso mostrata quando c'e una attesa nel caricamento dei dati*/
ProgressBar progressBar;
/**Spinner per scegliere la giornata del campionato di cui visualizzare le partite*/
Spinner spinner;
/**RecyclerView contenente le Card delle partite*/
RecyclerView recyclerList;
/**Giornata del campionato scelta*/
private int giornata;
/**
* Inizializza il fragment con il campionato scelto.
* @param IDCampionato Il campionato scelto
* @return Fragment il fragment PagePartite
*/
public static Fragment newInstance(int IDCampionato) {
PagePartite fragment = new PagePartite();
idcampionato=IDCampionato;
return fragment;
}
/**
* Costruttore vuoto richiesto
*/
public PagePartite(){
//required empty public constructor
}
/**
* Funzione che inizializza i dati del Fragment
* @param savedInstanceState
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* Funzione che crea la grafica del Fragment definito nella funzione newIstance.Inizializza la RecyclerView con le View delle Card, lo SwipeRefreshLayout
* @param inflater Layout utilizzato per creare la grafica
* @param container Container del Fragment
* @param savedInstanceState
* @return View rappresentante il fragment
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//inflates the view inside ViewPager
view = inflater.inflate(R.layout.fragment_partite, container, false);
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.partite_swipe_refresh_layout);
mSwipeRefreshLayout.setColorSchemeResources(R.color.colore_sfondo_menu, R.color.indicator_color, R.color.colore_menu);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refresh();
}
});
giornata=1;
spinner = (Spinner) view.findViewById(R.id.spinner);
//adding recyclerList and setting its layout
recyclerList = (RecyclerView) view.findViewById(R.id.cardList);
recyclerList.setHasFixedSize(true);
LinearLayoutManager layout = new LinearLayoutManager(view.getContext());
layout.setOrientation(LinearLayoutManager.VERTICAL);
recyclerList.setLayoutManager(layout);
getGiornate();
getPartite();
return view;
}
/**
* Funzione che riceve i risultati delle partite dopo aver effettuato una Richiesta HTTP,e li formatta all'interno di Card
*/
public void getPartite(){
wsURL = "http://fihresults.altervista.org/WebServiceFihResults/service.php";
if(hasConnection(view.getContext())) {
HTTPRequest http=new HTTPRequest() {
@Override
protected void onPreExecute() {
mSwipeRefreshLayout.setRefreshing(true);
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
return super.doInBackground(params);
}
@Override
protected void onPostExecute(String result) {
mSwipeRefreshLayout.setRefreshing(false);
super.onPostExecute(result);
Log.i("INFO getPartite", result);
JSONArray dati = null;
ArrayList partite = new ArrayList();
try {
dati = new JSONArray(result);
for(int i=0;i<dati.length();i++) {
JSONObject jsonobject = dati.getJSONObject(i);
partite.add(new Partita(jsonobject));
}
} catch (JSONException e) {
e.printStackTrace();
}
CardAdapter cardadapt = new CardAdapter(0,partite);
recyclerList.setAdapter(cardadapt);
}
};
http.execute(wsURL, "4", "mostraPartite", "IDCampionato", String.valueOf(idcampionato), "NumGiornata", String.valueOf(giornata));
}
else
Toast.makeText(view.getContext(),"Connessione Internet assente",Toast.LENGTH_LONG).show();
}
/**
* Funzione che effettua una richiesta HTTP per ricevere il numero di giornate del campionato,quindi inserisce tali dati all'interno dello Spinner
*/
public void getGiornate() {
Log.i("INFO PagePartite", "ESEGUO getGiornate()");
wsURL = "http://fihresults.altervista.org/WebServiceFihResults/service.php";
if(hasConnection(view.getContext())) {
HTTPRequest http=new HTTPRequest() {
@Override
protected void onPreExecute() {
if(!mSwipeRefreshLayout.isRefreshing())
mSwipeRefreshLayout.setRefreshing(true);
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
return super.doInBackground(params);
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i("INFO getGiornate",result);
int numgiornate;
ArrayList<String> giornate = new ArrayList();
JSONArray dati = null;
try {
dati = new JSONArray(result);
JSONObject jsonobject = dati.getJSONObject(0);
numgiornate= jsonobject.getInt("NumGiornate");
for(int i=1;i<=numgiornate;i++) {
String riga = "Giornata "+i;
giornate.add(riga);
}
} catch (JSONException e) {
e.printStackTrace();
}
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(view.getContext(),
android.R.layout.simple_list_item_1,giornate);
spinner.setAdapter(adapter);
}
};
http.execute(wsURL, "2", "getMaxGiornate", "IDCampionato", String.valueOf(idcampionato));
spinner.setOnItemSelectedListener(this);
}
else
Toast.makeText(view.getContext(),"Connessione Internet assente",Toast.LENGTH_LONG).show();
}
/**
* Funzione che cambia i dati a seconda della giornata selezionata all'interno dello spinner
* @param parent Parent dello Spinner
* @param view View
* @param position Posizione selezionata all'interno dello spinner
* @param id
*/
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
giornata=position+1;
getPartite();
}
/**
* Funzione che effettua il refresh dei dati della pagina
*/
public void refresh(){
getGiornate();
getPartite();
}
}
编辑:
FragmentPagerAdapter
package com.dcdeveloper.fihresults;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.util.Log;
import android.view.View;
/**
* Adapter per l'inserimento del frammento in un ViewPager.
* Settato per contenere tre pagine, "Partite","Classifica" e "Statistiche"
* Created by Dario on 06/06/2015.
*
*/
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 3;
private String tabTitles[] = new String[] { "Partite", "Classifica", "Statistiche" };
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
protected int idcampionato=1; //default value
@Override
public int getCount() {
return PAGE_COUNT;
}
/**
* Funzione richiamata quando un Fragment non è inizializzato,come all'avvio dell'applicazione.Restituisce il Fragment creato.
* @param position Posizione in cui creare il Fragment
* @return Fragment appena creato ed inserito nell'Adapter
*/
@Override
public Fragment getItem(int position) {
Fragment fragment=null;
Log.i("MyFragmentPagerAdapter "+(String)getPageTitle(position),Integer.toString(position));
switch(position) {
//when created,cards will get the default value (idcampionato=1)
case 0:
fragment = PagePartite.newInstance(idcampionato);
break;
case 1:
fragment = PageClassifica.newInstance(idcampionato);
break;
case 2:
fragment = PageStatistiche.newInstance(idcampionato);
break;
}
return fragment;
}
/**
* Ritorna il titolo della pagina corrente
* @param position posizione corrente
* @return Charsequence che rappresenta il titolo
*/
@Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
return tabTitles[position];
}
}
【问题讨论】:
标签: android android-fragments android-viewpager android-cardview fragmentmanager