android - उपय - विद्यालय पुस्तकालय के नियम




एंड्रॉइड 4.0, 4.1(<4.2) में नेस्टेड टुकड़ों के लिए सर्वश्रेष्ठ अभ्यास समर्थन पुस्तकालय का उपयोग किए बिना (4)

सीमाएं

तो आप किसी अन्य टुकड़े के अंदर घोंसले के टुकड़े एक्सएमएल के साथ संभव नहीं हैं, भले ही आप FragmentManager का किस संस्करण का उपयोग करते हैं।

तो आपको कोड के माध्यम से टुकड़े जोड़ना होगा, यह एक समस्या की तरह प्रतीत हो सकता है, लेकिन लंबे समय तक आपके लेआउट superflexible बनाता है।

तो getChildFragmentManger का उपयोग किए बिना घोंसला? childFragmentManager पीछे सार यह है कि यह पिछले खंड लेनदेन समाप्त होने तक लोडिंग को childFragmentManager है। और निश्चित रूप से यह केवल 4.2 या समर्थन पुस्तकालय में स्वाभाविक रूप से समर्थित था।

ChildManager के बिना घोंसला - समाधान

समाधान, ज़रूर! मैं इसे लंबे समय से कर रहा हूं, (चूंकि ViewPager की घोषणा की गई थी)।

निचे देखो; यह एक Fragment जो लोडिंग को रोकता है, इसलिए इसके अंदर Fragment को लोड किया जा सकता है।

यह बहुत आसान है, Handler वास्तव में वास्तव में आसान वर्ग है, प्रभावी रूप से हैंडलर वर्तमान थ्रेड लेनदेन के समाप्त होने के बाद मुख्य धागे पर निष्पादित करने के लिए एक स्थान की प्रतीक्षा करता है (चूंकि टुकड़े मुख्य थ्रेड पर चलने वाले यूआई के साथ हस्तक्षेप करते हैं)।

// Remember this is an example, you will need to modify to work with your code
private final Handler handler = new Handler();
private Runnable runPager;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    return inflater.inflate(R.layout.frag_layout, container, false);
}

@Override
public void onActivityCreated(Bundle savedInstanceState)
{
    super.onActivityCreated(savedInstanceState);
    runPager = new Runnable() {

        @Override
        public void run()
        {
          getFragmentManager().beginTransaction().addFragment(R.id.frag_container, MyFragment.newInstance()).commit();
        }
    };
    handler.post(runPager);
}

/**
 * @see android.support.v4.app.Fragment#onPause()
 */
@Override
public void onPause()
{
    super.onPause();
    handler.removeCallbacks(runPager);
}

मैं इसे 'सर्वश्रेष्ठ अभ्यास' नहीं मानूंगा, लेकिन मेरे पास इस हैक का उपयोग करके लाइव ऐप्स हैं और मुझे इसके साथ कोई समस्या नहीं है।

मैं दृश्य पेजर्स को एम्बेड करने के लिए इस विधि का भी उपयोग करता हूं - https://gist.github.com/chrisjenx/3405429

मैं 4.0 और 4.1 टैबलेट के लिए एक ऐप लिख रहा हूं, जिसके लिए मैं समर्थन पुस्तकालयों (यदि आवश्यक नहीं है) का उपयोग नहीं करना चाहता हूं , लेकिन इसलिए 4.x एपीआई इसलिए।

तो मेरा लक्ष्य मंच बहुत अच्छी तरह परिभाषित है:> = 4.0 और <= 4.1

ऐप में एक बहु-फलक लेआउट (दो टुकड़े, बाईं ओर एक छोटा, दाईं ओर एक सामग्री खंड) और टैब के साथ एक एक्शन बार है।

इसी तरह:

एक्शन बार पर एक टैब पर क्लिक करने से 'बाहरी' खंड बदल जाता है, और आंतरिक टुकड़ा तब दो घोंसले वाले टुकड़ों (1. छोटी बाएं सूची खंड, 2. विस्तृत सामग्री खंड) के साथ एक टुकड़ा होता है।

अब मैं सोच रहा हूं कि टुकड़ों और विशेष रूप से घोंसले के टुकड़ों को बदलने के लिए सबसे अच्छा अभ्यास क्या है। ViewPager समर्थन पुस्तकालय का हिस्सा है, इस वर्ग के लिए कोई मूल 4.x विकल्प नहीं है। मेरी समझ में 'बहिष्कृत' होने लगते हैं। - http://developer.android.com/reference/android/support/v4/view/ViewPager.html

फिर मैंने एंड्रॉइड 4.2 के लिए रिलीज नोट्स को ChildFragmentManager बारे में ChildFragmentManager , जो एक अच्छा फिट होगा, लेकिन मैं 4.0 और 4.1 को लक्षित कर रहा हूं, इसलिए इसका उपयोग नहीं किया जा सकता है।

ChildFragmentManager केवल 4.2 में उपलब्ध है

दुर्भाग्यवश, वहां कोई भी अच्छा उदाहरण नहीं है जो समर्थन पुस्तकालय के बिना टुकड़े के उपयोग के लिए सर्वोत्तम प्रथाओं को दिखाता है, यहां तक ​​कि पूरे एंड्रॉइड डेवलपर गाइड में भी; और विशेष रूप से नेस्टेड टुकड़ों के बारे में कुछ भी नहीं।

तो मैं सोच रहा हूं: क्या समर्थन पुस्तकालय और इसके साथ आने वाली हर चीज़ का उपयोग किए बिना नेस्टेड टुकड़ों वाले 4.1 ऐप्स लिखना संभव नहीं है? (Fragment, आदि के बजाय FragmentActivity का उपयोग करने की आवश्यकता है?) या सबसे अच्छा अभ्यास क्या होगा?

वर्तमान में विकास में जो समस्या है, वह वास्तव में यह बयान है:

एंड्रॉइड सपोर्ट लाइब्रेरी अब भी नेस्टेड टुकड़ों का समर्थन करती है, ताकि आप एंड्रॉइड 1.6 और उच्चतर पर नेस्टेड टुकड़े डिज़ाइन को कार्यान्वित कर सकें।

नोट: उस लेआउट में <fragment> शामिल होने पर आप एक लेआउट को एक टुकड़े में नहीं बढ़ा सकते हैं। नेस्टेड टुकड़े केवल तभी समर्थित होते हैं जब गतिशील रूप से एक खंड में जोड़ा जाता है।

क्योंकि मैं एक्सएमएल में नेस्टेड टुकड़े को परिभाषित करता हूं, जो स्पष्ट रूप से एक त्रुटि का कारण बनता है:

Caused by: java.lang.IllegalArgumentException: Binary XML file line #15: Duplicate id 0x7f090009, tag frgCustomerList, or parent id 0x7f090008 with another fragment for de.xyz.is.android.fragment.CustomerListFragment_

फिलहाल, मैं अपने लिए निष्कर्ष निकाला हूं: यहां तक ​​कि 4.1 पर, जब भी मैं 2.x प्लेटफार्म को लक्षित नहीं करना चाहता, स्क्रीनशॉट में दिखाए गए घोंसले वाले टुकड़े समर्थन लाइब्रेरी के बिना संभव नहीं हैं।

(यह वास्तव में एक प्रश्न की तुलना में विकी प्रविष्टि से अधिक हो सकता है, लेकिन हो सकता है कि किसी और ने इसे पहले प्रबंधित किया हो)।

अद्यतन करें:

एक सहायक उत्तर यहां है: टुकड़े टुकड़े के अंदर टुकड़े


@ क्रिस.जेनकिन्स के उत्तर पर बिल्डिंग, यह वह समाधान है जो मेरे लिए अच्छी तरह से काम कर रहा है, जीवन चक्र घटनाओं के दौरान खंड (ओं) को हटाने के लिए (जिसमें IllegalStateExceptions को फेंकने की प्रवृत्ति है)। यह हैंडलर दृष्टिकोण के संयोजन का उपयोग करता है, और एक गतिविधि .isFinishing () चेक (अन्यथा यह "त्रुटि के बाद इस क्रिया को निष्पादित नहीं कर सकता है" के लिए एक त्रुटि फेंक देगा।

import android.app.Activity;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

public abstract class BaseFragment extends Fragment {
    private final Handler handler = new Handler();

    /**
     * Removes the {@link Fragment} using {@link #getFragmentManager()}, wrapped in a {@link Handler} to
     * compensate for illegal states.
     *
     * @param fragment The {@link Fragment} to schedule for removal.
     */
    protected void removeFragment(@Nullable final Fragment fragment) {
        if (fragment == null) return;

        final Activity activity = getActivity();
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (activity != null && !activity.isFinishing()) {
                    getFragmentManager().beginTransaction()
                            .remove(fragment)
                            .commitAllowingStateLoss();
                }
            }
        });
    }

    /**
     * Removes each {@link Fragment} using {@link #getFragmentManager()}, wrapped in a {@link Handler} to
     * compensate for illegal states.
     *
     * @param fragments The {@link Fragment}s to schedule for removal.
     */
    protected void removeFragments(final Fragment... fragments) {
        final FragmentManager fragmentManager = getFragmentManager();
        final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        for (Fragment fragment : fragments) {
            if (fragment != null) {
                fragmentTransaction.remove(fragment);
            }
        }

        final Activity activity = getActivity();
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (activity != null && !activity.isFinishing()) {
                    fragmentTransaction.commitAllowingStateLoss();
                }
            }
        });
    }
}

उपयोग:

class MyFragment extends Fragment {
    @Override
    public void onDestroyView() {
        removeFragments(mFragment1, mFragment2, mFragment3);
        super.onDestroyView();
    }
}

मुझे नेविगेशन ड्रावर, टैबहोस्ट और व्यूपेगर के संयोजन के कारण इस सटीक मुद्दे से निपटना पड़ा, जिसमें टैबहोस्ट की वजह से समर्थन लाइब्रेरी के उपयोग के साथ जटिलताएं थीं। और फिर मुझे जेलीबीन 4.1 के न्यूनतम एपीआई का भी समर्थन करना पड़ा, इसलिए GetChildFragmentManager के साथ नेस्टेड टुकड़ों का उपयोग करना एक विकल्प नहीं था।

तो मेरी समस्या को आसवित किया जा सकता है ...

TabHost (for top level)
+ ViewPager (for just one of the top level tabbed fragments)
= need for Nested Fragments (which JellyBean 4.1 won't support)

मेरा समाधान वास्तव में टुकड़े टुकड़े किए बिना घोंसले टुकड़ों के भ्रम पैदा करना था। मैंने मुख्य गतिविधि को टैबबॉस्ट और व्यूपेजर का उपयोग करके दो भाई दृश्यों का प्रबंधन करने के लिए किया, जिनकी दृश्यता 0 और 1 के बीच लेआउट_वेट को टॉगल करके प्रबंधित की जाती है।

//Hide the fragment used by TabHost by setting height and weight to 0
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 0);
mTabHostedView.setLayoutParams(lp);
//Show the fragment used by ViewPager by setting height to 0 but weight to 1
lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 1);
mPagedView.setLayoutParams(lp);

इसने प्रभावी रूप से प्रासंगिक लेआउट वजन को प्रबंधित करने तक मेरे नकली "नेस्टेड फ्रैगमेंट" को एक स्वतंत्र दृश्य के रूप में संचालित करने की अनुमति दी।

यहां मेरी गतिविधि_माइन.एक्सएमएल है:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.ringofblades..app.MainActivity">

    <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <FrameLayout android:id="@android:id/tabcontent"
                android:background="@drawable/background_image"
                android:layout_width="match_parent"
                android:layout_weight="0.5"
                android:layout_height="0dp"/>
            <android.support.v4.view.ViewPager
                xmlns:tools="http://schemas.android.com/tools"
                android:id="@+id/pager"
                android:background="@drawable/background_image"
                android:layout_width="match_parent"
                android:layout_weight="0.5"
                android:layout_height="0dp"
                tools:context="com.ringofblades..app.MainActivity">
                <FrameLayout
                    android:id="@+id/container"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
            </android.support.v4.view.ViewPager>
            <TabWidget android:id="@android:id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </TabHost>

    <fragment android:id="@+id/navigation_drawer"
        android:layout_width="@dimen/navigation_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:name="com.ringofblades..app.NavigationDrawerFragment"
        tools:layout="@layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>

ध्यान दें कि "@ + id / पेजर" और "@ + आईडी / कंटेनर" भाई बहन हैं 'एंड्रॉइड: लेआउट_वेट = "0.5"' और 'एंड्रॉइड: layout_height = "0dp"'। ऐसा इसलिए है कि मैं इसे किसी भी स्क्रीन आकार के लिए पूर्वावलोकनकर्ता में देख सकता हूं। वैसे भी रनटाइम के दौरान उनके वजन कोड में छेड़छाड़ की जाएगी।


हालांकि ओपी में विशेष परिस्थितियां हो सकती हैं जो उन्हें समर्थन पुस्तकालय का उपयोग करने से रोकती हैं, ज्यादातर लोगों को इसका उपयोग करना चाहिए। एंड्रॉइड प्रलेखन इसकी सिफारिश करता है, और यह आपके ऐप को व्यापक दर्शकों के लिए उपलब्ध कराएगा।

यहां मेरे पूर्ण उत्तर में मैंने एक उदाहरण दिया है कि समर्थन लाइब्रेरी के साथ नेस्टेड टुकड़ों का उपयोग कैसे किया जाए।







android-nested-fragment