5

Ho riscontrato uno strano problema durante l'utilizzo della libreria di supporto.Android - Frammento dalla libreria di supporto non compatibile con la piattaforma 4.3


io voglio fare uno schede di navigazione dinamico con frammenti di commutazione sulla piattaforma 2.3.3, proprio come quello che ha fatto API Demo.

enter image description here


tutto va bene su 2.3.3 piattaforma, ma quando ho preso uno sguardo alla stessa attività sulla piattaforma 4.3, ho scoperto che qualcosa di molto strano.

il SupportFragmentManagement non è in grado di staccare il frammento, sembra che la scheda che seleziona il callback non sia stata eseguita correttamente;

seguenti immagini mostrano come il mio demo andare enter image description here

ed ecco il mio codice:

package net.zengweizhi.android.gettingstarted.lesson05.test; 
import net.zengweizhi.android.gettingstarted.R; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

// utilizzando l'API dalla libreria di supporto

import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentTransaction; 
import android.support.v7.app.ActionBar; 
import android.support.v7.app.ActionBar.Tab; 
import android.support.v7.app.ActionBar.TabListener; 
import android.support.v7.app.ActionBarActivity; 
public class NavigationTabsWithFragmentsV9 extends ActionBarActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
    } 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.activity_navigation_tabs, menu); 
     return super.onCreateOptionsMenu(menu); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case R.id.actionButton_addTab: 
      addTab(); 
      break; 
     case R.id.actionButton_removeTab: 
      removeTab(); 
      break; 
     default: 
      break; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    private int mTabSeq = 0; 

    private void addTab(){ 
     getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

     mTabSeq++; 

     Tab tab = getSupportActionBar().newTab(); 
     tab.setText("TAB " + mTabSeq); 
     tab.setTabListener(new MyTabListener(this)); 
     getSupportActionBar().addTab(tab); 
    } 

    private void removeTab(){ 
     Tab tab = getSupportActionBar().getSelectedTab(); 
     getSupportActionBar().removeTab(tab); 

     Fragment fragment = getSupportFragmentManager().findFragmentByTag(tab.getText().toString()); 
     getSupportFragmentManager().beginTransaction().remove(fragment).commit(); 
     if(getSupportActionBar().getTabCount() == 0){ 
      getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 
     } 
    } 

    private static final class MyTabListener implements TabListener { 
     private NavigationTabsWithFragmentsV9 mActivity; 
     public MyTabListener(NavigationTabsWithFragmentsV9 activity /*,Fragment fragment*/){ 
      mActivity = activity; 
     } 

     @Override 
     public void onTabReselected(Tab tab, FragmentTransaction ft) { 
      // Do nothing 
     } 

     @Override 
     public void onTabSelected(Tab tab, FragmentTransaction ft) { 
      Object obj = tab.getTag(); 
      if(null == obj){ 
       Bundle args = new Bundle(); 
       args.putString(SimpleFragment.EXTRA_OUTPUT_MESSAGE, tab.getText().toString()); 
       Fragment fragment = Fragment.instantiate(mActivity, SimpleFragment.class.getName(), args); 
       ft.add(android.R.id.content, fragment, tab.getText().toString()); 

       tab.setTag(obj = fragment); 
      } 

      ft.attach((Fragment)obj); 
     } 

     @Override 
     public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
      if(null != mActivity.getSupportFragmentManager().findFragmentByTag(tab.getText().toString())){ 
       ft.detach((Fragment)tab.getTag()); 
      } 
     } 

    } 

    public static final class SimpleFragment extends Fragment { 
     public static final String EXTRA_OUTPUT_MESSAGE = "output_message"; 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
      View fragmentView = inflater.inflate(R.layout.fragment_simple, container, false); 

      String outputMesasge = null; 
      if(null != getArguments()){ 
       outputMesasge = getArguments().getString(EXTRA_OUTPUT_MESSAGE); 
      } 
      if(null == outputMesasge || 0 == outputMesasge.trim().length()){ 
       outputMesasge = getString(R.string.demo_text); 
      } 
      TextView textView = (TextView) fragmentView.findViewById(R.id.textView_simpleFragmentOutput); 
      textView.setText(outputMesasge); 

      return fragmentView; 
     } 
    } 
} 

Ma quando cambio tutto il support api al regular api(default platform api), tutto va bene su 4,3 piattaforma (ma questo non lo fa compatibile con la piattaforma 2.3.3);

enter image description here

ecco la (differenza nulla tranne l'ActionBar e Fragment API) Codice

package net.zengweizhi.android.gettingstarted.lesson05.test; 

import net.zengweizhi.android.gettingstarted.R; 
import android.os.Bundle; 
import android.support.v7.app.ActionBarActivity; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

// utilizzare l'API di piattaforma di default (solo in v11 e successivi)

import android.annotation.SuppressLint; 
import android.app.ActionBar; 
import android.app.ActionBar.Tab; 
import android.app.ActionBar.TabListener; 
import android.app.Fragment; 
import android.app.FragmentTransaction; 

@SuppressLint ("NewApi")

public class NavigationTabsWithFragmentsV14 extends ActionBarActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
    } 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.activity_navigation_tabs, menu); 
     return super.onCreateOptionsMenu(menu); 
    } 

    private int mTabSeq = 0; 

    private void addTab(){ 
     getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
     mTabSeq++; 

     Tab tab = getActionBar().newTab(); 
     tab.setText("TAB " + mTabSeq); 
     tab.setTabListener(new MyTabListener(this)); 
     getActionBar().addTab(tab); 
    } 

    private void removeTab(){ 
     Tab tab = getActionBar().getSelectedTab(); 
     getActionBar().removeTab(tab); 

     Fragment fragment = getFragmentManager().findFragmentByTag(tab.getText().toString()); 
     getFragmentManager().beginTransaction().remove(fragment).commit(); 
     if(getActionBar().getTabCount() == 0){ 
      getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 
     } 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case R.id.actionButton_addTab: 
      addTab(); 
      break; 
     case R.id.actionButton_removeTab: 
      removeTab(); 
      break; 
     default: 
      break; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    private static final class MyTabListener implements TabListener { 
     private NavigationTabsWithFragmentsV14 mActivity; 
     public MyTabListener(NavigationTabsWithFragmentsV14 activity /*,Fragment fragment*/){ 
      mActivity = activity; 
     } 

     @Override 
     public void onTabReselected(Tab tab, FragmentTransaction ft) { 
      // Do nothing 
     } 

     @Override 
     public void onTabSelected(Tab tab, FragmentTransaction ft) { 
      Object obj = tab.getTag(); 
      if(null == obj){ // initialize fragment to tab 
       Bundle args = new Bundle(); 
       args.putString(SimpleFragment.EXTRA_OUTPUT_MESSAGE, tab.getText().toString()); 
       Fragment fragment = Fragment.instantiate(mActivity, SimpleFragment.class.getName(), args); 
       ft.add(android.R.id.content, fragment, tab.getText().toString()); 

       tab.setTag(obj = fragment); 
      } 
      ft.attach((Fragment)obj); 
     } 

     @Override 
     public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
      if(null != mActivity.getFragmentManager().findFragmentByTag(tab.getText().toString())){ 
       ft.detach((Fragment)tab.getTag()); 
      } 
     } 
    } 

    public static final class SimpleFragment extends Fragment { 
     public static final String EXTRA_OUTPUT_MESSAGE = "output_message"; 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
      View fragmentView = inflater.inflate(R.layout.fragment_simple, container, false); 

      String outputMesasge = null; 
      if(null != getArguments()){ 
       outputMesasge = getArguments().getString(EXTRA_OUTPUT_MESSAGE); 
      } 
      if(null == outputMesasge || 0 == outputMesasge.trim().length()){ 
       outputMesasge = getString(R.string.demo_text); 
      } 
      TextView textView = (TextView) fragmentView.findViewById(R.id.textView_simpleFragmentOutput); 
      textView.setText(outputMesasge); 

      return fragmentView; 
     } 
    } 
} 

posso fare una versione compatibile utilizzando (valori-V14/classes.xml) e codice seguente

try { 
    Class<?> clazz = Class.forName(getString(R.string.class_navigationTabsAndFragmentsActivity)); 
    startActivity(clazz); 
} catch (ClassNotFoundException ex) { 
    showTextByToast(ex.getMessage()); 
} 

ma ho ancora voglio sapere cosa sta succedendo nella versione support library, qualcuno può aiutarmi a capire questo problema?

+1

http: // StackOverflow.it/questions/19642295/actionbar-tab-contents-overlapping/19644639 # 19644639 – Luksprog

+0

Grazie mille @Luksprog; Che strano, il team di Android non ha realizzato questo promettente, o l'ha semplicemente modificato per altri scopi? Dovrei comunque utilizzare la libreria di supporto; ha lasciato un insetto come quello a cui piace un boom temporale; –

+1

Non so se qualcuno ha pubblicato un bug report. Userò ancora la libreria e sarò in guardia per un aggiornamento del pacchetto di compatibilità (che viene più spesso) che potrebbe risolverlo. – Luksprog

risposta

2

Google rilascia Nexus 5 e una nuova libreria di supporto (V19), questa versione fissa questo bug enter image description here