2012-01-16 16 views
11

मेरे पास एक बहुत ही सरल कोड है जहां मैं टैब खंडों के साथ एक्शन बार का उपयोग करता हूं। यह लोड के बाद ठीक काम करता है, लेकिन अभिविन्यास परिवर्तन के बाद यह पागल हो जाता है। पुराना टुकड़ा भी दिखाई देता है (क्यों?)।स्क्रॉलव्यू के साथ एंड्रॉइड एक्शन बार टैब ने अभिविन्यास परिवर्तन के बाद डुप्लिकेट दृश्य बनाया

छवि पर हंगेरियन ग्रंथों के लिए खेद है, लेकिन मुझे उम्मीद है कि इससे कोई फर्क नहीं पड़ता। After orientation change

मैं कोड संलग्न करता हूं, शायद यह इस समस्या को हल करने में मदद करता है।

मुख्य गतिविधि:

public class Main extends Activity 
{ 
    private static ActionBar actionBar; 

    @Override 
    protected void onCreate(final Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     // setup action bar for tabs 
     actionBar = getActionBar(); 
     actionBar.removeAllTabs(); 
     if (actionBar.getTabCount() == 0) 
     { 
      actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

      Tab tab = actionBar.newTab().setText(R.string.starter).setTabListener(new TabListener<Starter>(this, "starter", Starter.class)); 
      actionBar.addTab(tab); 

      tab = actionBar.newTab().setText(R.string.newword).setTabListener(new TabListener<NewWord>(this, "newwod", NewWord.class)); 
      actionBar.addTab(tab); 

      tab = actionBar.newTab().setText(R.string.feedback).setTabListener(new TabListener<Feedback>(this, "feedback", Feedback.class)); 
      actionBar.addTab(tab); 
     } 

     if (savedInstanceState != null) 
     { 
      actionBar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0)); 
     } 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) 
    { 
     super.onSaveInstanceState(outState); 
     outState.putInt("tab", getActionBar().getSelectedNavigationIndex()); 
    } 
} 

TabListener (गूगल उदाहरण के रूप में ही):

public class TabListener<T extends Fragment> implements android.app.ActionBar.TabListener 
{ 
    private Fragment mFragment; 
    private final Activity mActivity; 
    private final String mTag; 
    private final Class<T> mClass; 

    /** 
    * Constructor used each time a new tab is created. 
    * 
    * @param activity 
    *   The host Activity, used to instantiate the fragment 
    * @param tag 
    *   The identifier tag for the fragment 
    * @param clz 
    *   The fragment's Class, used to instantiate the fragment 
    */ 
    public TabListener(Activity activity, String tag, Class<T> clz) 
    { 
     mActivity = activity; 
     mTag = tag; 
     mClass = clz; 
    } 

    @Override 
    public void onTabReselected(Tab tab, FragmentTransaction ft) 
    { 
     // User selected the already selected tab. Usually do nothing. 

    } 

    @Override 
    public void onTabSelected(Tab tab, FragmentTransaction ft) 
    { 
     // Check if the fragment is already initialized 
     if (mFragment == null) 
     { 
      // If not, instantiate and add it to the activity 
      mFragment = Fragment.instantiate(mActivity, mClass.getName()); 
      ft.add(android.R.id.content, mFragment, mTag); 
     } else 
     { 
      // If it exists, simply attach it in order to show it 
      ft.attach(mFragment); 
     } 

    } 

    @Override 
    public void onTabUnselected(Tab tab, FragmentTransaction ft) 
    { 
     if (mFragment != null) 
     { 
      // Detach the fragment, because another one is being attached 
      ft.detach(mFragment); 
     } 
    } 

} 

टुकड़ा:

public class Starter extends Fragment 
{ 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     setRetainInstance(false); 
     return inflater.inflate(R.layout.newword, container, false); 
    } 
} 

और लेआउट एक्सएमएल:

<?xml version="1.0" encoding="utf-8"?> 
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:padding="5dp" > 

    <LinearLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" > 

     <TextView 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:padding="5dp" 
      android:text="@string/newword" 
      android:textAppearance="?android:attr/textAppearanceMedium" /> 

     <EditText 
      android:id="@+id/newwordtext" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:hint="@string/wordhint" /> 

     <TextView 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:padding="5dp" 
      android:text="@string/description" 
      android:textAppearance="?android:attr/textAppearanceMedium" 
      android:textStyle="bold" /> 

     <EditText 
      android:id="@+id/descriptionwordtext" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:hint="@string/descriptionhint" 
      android:inputType="textMultiLine" 
      android:minLines="4" /> 

     <TextView 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:padding="5dp" 
      android:text="@string/origin" 
      android:textAppearance="?android:attr/textAppearanceMedium" 
      android:textStyle="bold" /> 

     <EditText 
      android:id="@+id/origintext" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:hint="@string/originhint" /> 

     <TextView 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:padding="5dp" 
      android:text="@string/source" 
      android:textAppearance="?android:attr/textAppearanceMedium" 
      android:textStyle="bold" /> 

     <EditText 
      android:id="@+id/sourcetext" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:hint="@string/sourcehint" /> 

     <TextView 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:padding="5dp" 
      android:text="@string/name" 
      android:textAppearance="?android:attr/textAppearanceMedium" 
      android:textStyle="bold" /> 

     <EditText 
      android:id="@+id/nametext" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:inputType="textPersonName" /> 

     <Button 
      android:id="@+id/sendbutton" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="right" 
      android:text="@string/send" /> 
    </LinearLayout> 

</ScrollView> 

अग्रिम में धन्यवाद!

उत्तर

5

मैं अन्य question में एक प्रयोग करने योग्य जवाब मिल गया है।

private class TabListener<T extends Fragment> implements android.app.ActionBar.TabListener 
    { 
     private Fragment mFragment; 
     private final Activity mActivity; 
     private final String mTag; 
     private final Class<T> mClass; 

     /** 
     * Constructor used each time a new tab is created. 
     * 
     * @param activity 
     *   The host Activity, used to instantiate the fragment 
     * @param tag 
     *   The identifier tag for the fragment 
     * @param clz 
     *   The fragment's Class, used to instantiate the fragment 
     */ 
     public TabListener(final Activity activity, final String tag, final Class<T> clz) 
     { 
      mActivity = activity; 
      mTag = tag; 
      mClass = clz; 
     } 

     @Override 
     public void onTabReselected(final Tab tab, final FragmentTransaction ft) 
     { 
      // User selected the already selected tab. Usually do nothing. 
     } 

     @Override 
     public void onTabSelected(final Tab tab, final FragmentTransaction ft) 
     { 
      mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag); 
      if (mFragment == null) 
      { 
       mFragment = Fragment.instantiate(mActivity, mClass.getName()); 
       ft.add(android.R.id.content, mFragment, mTag); 
      } 
      else 
      { 
       ft.attach(mFragment); 
      } 
     } 

     @Override 
     public void onTabUnselected(final Tab tab, final FragmentTransaction ft) 
     { 
      if (mFragment != null) 
      { 
       ft.detach(mFragment); 
      } 
     } 
    } 

तो इससे पहले कि मैं टुकड़ा (फिर) जोड़ने के लिए, मैं इसे अस्तित्व (और उसके संदर्भ मिलता है) की जाँच करें:

मैं अपने TabListener संशोधित करने के लिए (मैं इसे आंतरिक वर्ग के रूप में मेरी मुख्य गतिविधि वर्ग में चले गए) की जरूरत है और यदि यह मौजूद है तो मैं इसे केवल संलग्न करता हूं।

+1

के लिए हल किया गया है, केवल एक चीज जो मैं जोड़ूंगा वह यह है कि यह लाइन "mFragment = mActivity.getFragmentManager()। FindFragmentByTag (mTag);" MFragment से पहले onTabUnelected विधि में भी जोड़ा जाना चाहिए! = शून्य जांच। अन्यथा, महान काम किया! – SBerg413

+0

mFragment = mActivity.getFragmentManager()। FindFragmentByTag (mTag); मेरी समस्या भी हल हो गई, कक्षा को आंतरिक और निजी होने की आवश्यकता नहीं है। – Goldorak84

2

ft.attach (mFragment) के स्थान पर ft.replace (R.id.content, mFragment) का उपयोग करने का प्रयास करें; onTabSelected समारोह है कि जैसे

+0

मैं इस के साथ की कोशिश की।।।: ft.replace (android.R.id.content, mFragment); लेकिन यह मदद नहीं करता है (एक ही समस्या करता है) और फिर टैब को फिर से चुनने के बाद टैब की पूरी सामग्री को ले जाएं। – sianis

+0

हे ...यह कोड मेरे लिए काम करता है: 'अगर (fragmentManager.findFragmentById (R.id.frame_for_fragment) == शून्य) { फ्रैगमेंट ट्रांज़ेक्शन खंडकरण ट्रांसलेशन = खंड प्रबंधक .beginTransaction(); खंड = नया कुछ फ़्रेगमेंट(); fragmentTransaction.add (R.id.frame_for_fragment, खंड); fragmentTransaction.commit(); } ' – Orest

+0

लेकिन मैं अपने आवेदन में अपना कोड कैसे डाल सकता हूं? – sianis

0
public void onTabSelected(Tab tab, FragmentTransaction ft) 
    { 
     // Check if the fragment is already initialized 
     if (mFragment == null) 
     { 
      if(ft.findFragmentById(android.R.id.content) == null){ 
      // If not, instantiate and add it to the activity 
      mFragment = Fragment.instantiate(mActivity, mClass.getName()); 
      ft.add(android.R.id.content, mFragment, mTag); 
      } 
     } else 
     { 
      // If it exists, simply attach it in order to show it 
      ft.attach(mFragment); 
     } 

    } 

कुछ में, क्योंकि आपके समस्या यह है कि अपने ही टुकड़ा दो बार जोड़ने है, हम बस जहां लगता है ...

1

मैं एक बहुत ही सरल समाधान पाया टुकड़े दोहराव से बचने के:

public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { 
     Fragment currentFragment = getFragmentManager().findFragmentByTag(CURRENT_FRAGMENT_TAG); 
     if (currentFragment == null || !currentFragment.getClass().equals(mFragment.getClass())) { 
      ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
      ft.add(android.R.id.content, mFragment, CURRENT_FRAGMENT_TAG); 
     } 
    } 

    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { 
     ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); 
     ft.remove(mFragment); 
    } 

समाधान की कुंजी हालत में है:

currentFragment == null || !currentFragment.getClass().equals(mFragment.getClass()) 

इस हालत वैध है तभी टुकड़े की कक्षाएं अलग है। यदि आपके पास एक ही कक्षा के अलग-अलग उदाहरण हैं तो आपको अपने कार्यों को पहचानने के लिए अपने टुकड़ों में एक अतिरिक्त विशेषता डालना होगा (या स्थिति के साथ सहयोग और स्थिति बनाने के लिए! CurrentFragment.getClass()। बराबर (mFragment.getClass()) सत्य : उदाहरण के लिए आप FragmentTransaction टैग सुविधा का उपयोग कर सकते हैं

अलविदा, एलेक्स

0

मैं सिर्फ टैब श्रोता निर्माता में टुकड़ा ऊपर देखकर भी इस हल

public class TabListener<T extends Fragment> implements ActionBar.TabListener 
{ 
    private Fragment fragment; 
    private final SherlockFragmentActivity activity; 
    private final String tag; 
    private final Class<T> clazz; 

    public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clazz) 
    { 
     this.activity = activity; 
     this.tag = tag; 
     this.clazz = clazz; 

     FragmentManager manager = ((SherlockFragmentActivity) activity).getSupportFragmentManager(); 
     fragment = manager.findFragmentByTag(tag); 
    } 
... 
}