ভিউপেজারে বর্তমান টুকরো উদাহরণটি পাওয়া যাচ্ছে


210

নীচে আমার কোড যা 3 Fragment classesপ্রতিটি 3 টি ট্যাব এর সাথে প্রতিটি এম্বেড করেছে ViewPager। আমার কাছে একটি মেনু বিকল্প রয়েছে। যেমনটি প্রদর্শিত হয়েছে onOptionsItemSelected(), একটি বিকল্প নির্বাচন করে আমাকে বর্তমানে প্রদর্শিত খণ্ডটি আপডেট করতে হবে। আপডেট করার জন্য আমাকে একটি পদ্ধতি কল করতে হবে যা খণ্ড শ্রেণিতে রয়েছে। কেউ দয়া করে এই পদ্ধতিটি কল করার পরামর্শ দিতে পারেন?

public class MainActivity  extends ActionBarActivity {

     ViewPager ViewPager;
     TabsAdapter TabsAdapter;

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

            ViewPager = new ViewPager(this);
            ViewPager.setId(R.id.pager);
            setContentView(ViewPager);

            final ActionBar bar = getSupportActionBar();

            bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

            //Attaching the Tabs to the fragment classes and setting the tab title.
            TabsAdapter = new TabsAdapter(this, ViewPager);
            TabsAdapter.addTab(bar.newTab().setText("FragmentClass1"),
                    FragmentClass1.class, null);
            TabsAdapter.addTab(bar.newTab().setText("FragmentClass2"),
              FragmentClass2.class, null);
            TabsAdapter.addTab(bar.newTab().setText("FragmentClass3"),
              FragmentClass3.class, null);


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

        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {

            switch (item.getItemId()) {

            case R.id.addText:

           **// Here I need to call the method which exists in the currently visible Fragment class**

                    return true;

            }

            return super.onOptionsItemSelected(item);
        }


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

     }

     public static class TabsAdapter extends FragmentPagerAdapter
      implements ActionBar.TabListener, ViewPager.OnPageChangeListener {

      private final Context mContext;
            private final ActionBar mActionBar;
            private final ViewPager mViewPager;
            private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

            static final class TabInfo {
                private final Class<?> clss;
                private final Bundle args;

                TabInfo(Class<?> _class, Bundle _args) {
                    clss = _class;
                    args = _args;
                }
            }

      public TabsAdapter(ActionBarActivity activity, ViewPager pager) {
       super(activity.getSupportFragmentManager());
                mContext = activity;
                mActionBar = activity.getSupportActionBar();
                mViewPager = pager;
                mViewPager.setAdapter(this);
                mViewPager.setOnPageChangeListener(this);
            }

      public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
                TabInfo info = new TabInfo(clss, args);
                tab.setTag(info);
                tab.setTabListener(this);
                mTabs.add(info);
                mActionBar.addTab(tab);
                notifyDataSetChanged();

            }

      @Override
      public void onPageScrollStateChanged(int state) {
       // TODO Auto-generated method stub

      }

      @Override
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
       // TODO Auto-generated method stub

      }

      @Override
      public void onPageSelected(int position) {
       // TODO Auto-generated method stub
       mActionBar.setSelectedNavigationItem(position);
      }

      @Override
      public void onTabReselected(Tab tab, FragmentTransaction ft) {
       // TODO Auto-generated method stub

      }

      @Override
      public void onTabSelected(Tab tab, FragmentTransaction ft) {
       Object tag = tab.getTag();
                for (int i=0; i<mTabs.size(); i++) {
                    if (mTabs.get(i) == tag) {
                        mViewPager.setCurrentItem(i);

                    }
                }

                tabPosition = tab.getPosition();
      }

      @Override
      public void onTabUnselected(Tab tab, FragmentTransaction ft) {
       // TODO Auto-generated method stub

      }

      @Override
      public Fragment getItem(int position) {
       TabInfo info = mTabs.get(position);
                return Fragment.instantiate(mContext, info.clss.getName(), info.args);
      }

      @Override
      public int getCount() {
       return mTabs.size();
      }

     }

    }

ধরুন নীচে updateList()আমি যে পদ্ধতিতে কল করতে চাইছি তার সাথে খণ্ড খণ্ড :

 public class FragmentClass1{

    ArrayList<String> originalData;


    @Override
         public View onCreateView(LayoutInflater inflater, ViewGroup container,
           Bundle savedInstanceState) {

          View fragmentView = inflater.inflate(R.layout.frag1, container, false);

          originalData = getOriginalDataFromDB();

          return fragmentView;

         }


    public void updateList(String text)
    {
       originalData.add(text);
       //Here I could do other UI part that need to added
    }
}

আপনি কল করতে চান খণ্ডের কোন পদ্ধতি?
বিরাজ জালাওয়াদিয়া

@ বিরাজজালাবাদিয়া আমার নিজস্ব নির্ধারিত পদ্ধতি, যার এতে একটি প্যারামিটার রয়েছে এবং সেই খণ্ড শ্রেণীর উদাহরণ ভেরিয়েবলগুলি ব্যবহার করে যা ইতিমধ্যে একটি ভিউ তৈরির সময় শুরু করা হয়েছিল।
রিক

1
ভিউপ্যাজারে থাকা আপনার টুকরোগুলির শ্রেণি নামটি কি আপনি দিতে পারেন?
বিরাজ জালাওয়াদিয়া


দৃশ্যমান খণ্ডগুলিকে অ্যাক্সেস করার সহজতম উপায়টি হবে স্ট্যাকওভারফ্লো / কোয়েশনস / 797979৯১65 / / এর মাধ্যমে , শীর্ষ দুটি উত্তর দেখুন।
Luksprog

উত্তর:


205

একটি বিকল্প নির্বাচন করে, আমার বর্তমানে উপস্থিত অংশগুলিকে আপডেট করতে হবে।

এটি করার একটি সহজ উপায় হ'ল FragmentPagerAdapterবাস্তবায়ন সম্পর্কিত একটি কৌশল ব্যবহার করা :

case R.id.addText:
     Fragment page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + ViewPager.getCurrentItem());
     // based on the current position you can then cast the page to the correct 
     // class and call the method:
     if (ViewPager.getCurrentItem() == 0 && page != null) {
          ((FragmentClass1)page).updateList("new item");     
     } 
return true;

শ্রেণীর নামটি ভেরিয়েবলের নাম হিসাবে ব্যবহার করে অত্যন্ত বিভ্রান্তিকর (তাই না ViewPager ViewPager, ViewPager mPagerউদাহরণস্বরূপ ব্যবহার করুন ) ব্যবহার করে আপনার পরিবর্তনশীল নামকরণ কনভেনশনটি পুনর্বিবেচনা করুন ।


23
সেই খণ্ডটি কি ভাবী-প্রুফ, যদি API পরিবর্তন হয়?
মার্টেন

7
@ মার্টেন না, এটি কেবলমাত্র একটি সাধারণ হ্যাক যা অ্যাডাপ্টার প্রদর্শিত হওয়ার পরে থেকেই ব্যবহৃত হয়েছে (এবং এর উত্স কোডটি উপলব্ধ ছিল), এটি এখনও পরিবর্তন হয়নি। আপনি যদি আরও নির্ভরযোগ্য কিছু চান তবে আপনাকে অন্যান্য বিকল্পগুলি ব্যবহার করতে হবে, সবচেয়ে উল্লেখযোগ্য instantiateItem()পদ্ধতিটি ওভাররাইডিং এবং নিজে সঠিক খণ্ডগুলির জন্য রেফারেন্স পেতে।
লুকসপ্রোগ

5
কয়েক ঘন্টা হতাশার পরে এবং সরাসরি পৃষ্ঠাগুলি জিজ্ঞাসা করার পরে mAdapter.getItem(position), দুর্দান্ত ... কমপক্ষে এখন আমি জানি যে অন্যান্য 8512 ট্রায়ালগুলি কার্যকর হয়নি। ধন্যবাদ
ডায়লর

29
আপনি যদি ফ্রেগমেন্টপেজারএডাপ্টার না করে ফ্রেগমেন্টস্টেটপেজারএডাপ্টার ব্যবহার করেন তবে এটি কাজ করে না তা নোট করুন।
শন লাউজন

3
@ শ্যাশনলাউজন ফ্রেগমেন্টস্টেটপেজারএডাপ্টারের একটি পৃথক বাস্তবায়ন রয়েছে, সেক্ষেত্রে দৃশ্যমান টুকরোগুলি পেতে আপনি তার ইনস্ট্যান্ট আইটেম () পদ্ধতিটি কল করেন।
লুকসপ্রোগ

155
    public class MyPagerAdapter extends FragmentPagerAdapter {
        private Fragment mCurrentFragment;

        public Fragment getCurrentFragment() {
            return mCurrentFragment;
        }
//...    
        @Override
        public void setPrimaryItem(ViewGroup container, int position, Object object) {
            if (getCurrentFragment() != object) {
                mCurrentFragment = ((Fragment) object);
            }
            super.setPrimaryItem(container, position, object);
        }
    }

28
গুগলের ফ্রেগমেন্টপেজএডাপ্টার.টিজেট কর্নারপ্রাইমারি আইটেম () প্রদান করা উচিত এমক্রেনারপ্রাইমারি আইটেম।
ইউজিন

1
আমি এই কৌশলটিও ব্যবহার করি I আমি পদ্ধতিগুলির সাথে একটি পেজারফ্র্যাগমেন্টও সংজ্ঞায়িত করি onPageSelected/ onPageDeselectedএবং আমার সমস্ত পেজার টুকরা এটি প্রসারিত করতে চাই। তারপরে setPrimaryitemব্যবহারকারীরা কোনও নতুন পৃষ্ঠায় সোয়াইপ করলে এই পদ্ধতিগুলিকে যথাযথভাবে কল করতে পারেন। এর অর্থ আপনি পাতাগুলিতে ডেটা লোড করার জন্য একটি অলস কৌশল বাস্তবায়ন করতে পারেন যা এমনকি দেখানো হয়নি। তবে আপনার মনে রাখা উচিত যে পৃষ্ঠার স্থানান্তরের সময় যদি পরবর্তী পৃষ্ঠাটি ইতিমধ্যে ডেটা দিয়ে জনিত থাকে তবে এটি আরও ভাল দেখায় তাই অলস সমস্ত ডেটা লোড onPageSelectedকরা আদর্শ নাও হতে পারে।
জেএইচ এইচ

3
ifবিবৃতি কেন ? খণ্ডটি কেবল equalsঅবজেক্টের পদ্ধতিতে কল করে , যা অগভীর তুলনা। তাহলে শুধু সবসময় কেন ফোন করবেন না mCurrentFragment = ((Fragment) object);?
ওভারক্লোভার

চেষ্টা করা হয়েছে এবং এটি দুর্দান্ত কাজ করে, কেবলমাত্র ফ্রন্টক্রেগমেন্টটি () এটি নির্দিষ্ট নির্দিষ্ট
খণ্ডে করা

113

প্রথমে সমস্ত "সক্রিয়" খণ্ড পৃষ্ঠার উপর নজর রাখুন। এই ক্ষেত্রে, আপনি ফ্র্যাগমেন্টস্টেটপেজারএডাপ্টারে খণ্ডিত পৃষ্ঠাগুলি ট্র্যাক করে রাখুন যা ভিউপ্যাজার দ্বারা ব্যবহৃত হয়।

@Override
public Fragment getItem(int index) {
    Fragment myFragment = MyFragment.newInstance();
    mPageReferenceMap.put(index, myFragment);
    return myFragment;
}

"নিষ্ক্রিয়" টুকরা পৃষ্ঠাগুলির একটি রেফারেন্স এড়াতে, আপনাকে ফ্রেগমেন্টস্টেটপেজারএডাপ্টারের ধ্বংস আইটেম (...) পদ্ধতিটি প্রয়োগ করতে হবে:

@Override
public void destroyItem (ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
    mPageReferenceMap.remove(position);
}

এবং যখন আপনাকে বর্তমানে দৃশ্যমান পৃষ্ঠাটি অ্যাক্সেস করতে হবে তখন আপনি ফোন করবেন:

int index = mViewPager.getCurrentItem();
MyAdapter adapter = ((MyAdapter)mViewPager.getAdapter());
MyFragment fragment = adapter.getFragment(index);

যেখানে মাইএডাপ্টারের গেটফ্রেগমেন্ট (ইনট) পদ্ধতিটি দেখতে এই রকম দেখাচ্ছে:

public MyFragment getFragment(int key) {
    return mPageReferenceMap.get(key);
}

আশা করি এটি সাহায্য করতে পারে!


আপনি দয়া করে পরিষ্কারভাবে ব্যাখ্যা করতে পারেন? আমার কোডে এই ফ্রেগমেন্টস্টেটপেজারএডাপ্টার ক্লাসটি রাখার দরকার নেই কোথায়? বিটিডব্লিউ আমার 3 টি টুকরো ক্লাস রয়েছে, একক মাইফ্রেগমেন্টক্লাস নেই।
রিক

7
আরও ভাল আপনি যদি এমপেজ রেফারেন্সম্যাপটি আপডেট আইটেমের পরিবর্তে ইনস্ট্যান্ট আইটেমে আপডেট করেন তবে এটি ওরিয়েন্টেশন পরিবর্তনের পরেও কাজ করে। '@ ওভাররাইড পাবলিক অবজেক্ট ইনস্ট্যান্টিয়েট আইটেম (ভিউগ্রুপ কনটেইনার, ইনট পজিশন) {টুকরা টুকরা = (টুকরা) সুপার.ইনস্ট্যানিয়েট আইটেম (ধারক, অবস্থান); এমপেজ রেফারেন্সম্যাপ.পুট (অবস্থান, খণ্ড); রিটার্ন টুকরা;
পেমেলাহো

এমপেজ রেফারেন্সম্যাপ কী?
DoruAdryan

10
এই উত্তরটি সত্যিই খারাপ! আপনার ভিউপ্যাজারের ক্যাশে ম্যানুয়ালি রাখা উচিত নয় যেহেতু এটি নিজেই হ্যান্ডেল করে। ভিউপ্যাজার সিদ্ধান্ত নেয় কখন খণ্ডটি বরাদ্দ করা উচিত বা না করা উচিত, কী বিরতি দেওয়া উচিত এবং যখন প্রতিটি খণ্ডে একটি রেফারেন্স রাখা কিছু অকেজো ওভারহেড যুক্ত করবে এবং মেমরিটির জন্য অনুকূল নয়।
লিভিও

3
আমি এই পদ্ধতির চেষ্টা করেছি কিন্তু দুর্ভাগ্যক্রমে যখন কার্যকলাপটি পুনরায় তৈরি করা হয় তখন এটি কাজ করে না। অ্যান্ড্রয়েড এন এবং তারপরে, মাল্টিউইন্ডো বৈশিষ্ট্যটি ব্যবহার করার সময় আপনি এটি দেখতে পাবেন। আপনার অ্যাপ্লিকেশনটি খোলা থাকলে, 'রিসেন্টস' বোতামটি (স্কয়ার এক) দীর্ঘ ধরে রাখুন। ক্রিয়াকলাপ এবং খণ্ডটি সেভড ইনস্ট্যান্সস্টেট থেকে পুনরায় তৈরি করা হয়েছে, অ্যাডাপ্টারটি পুনরায় তৈরি করা হয়েছে (সুতরাং এমপেজেরিফারেন্সম্যাপটি এখন খালি), তবে গেটআইটিমে আবার কল হয় না। মানচিত্রটি খালি থাকে তাই অ্যাডাপ্টার.জেটফ্র্যাগমেন্ট (সূচক) ক্রাশ হবে।
মার্টিন কোনিসেক

102

এই নির্দিষ্ট খণ্ড শ্রেণীর উদাহরণ ভেরিয়েবলের জন্য আমি নলপয়েন্টারএক্সসেপশনটি পাচ্ছি না only এটি একই জিনিসটিতে আটকে থাকা অন্যদের জন্য সহায়ক হতে পারে। On অপশন আইটেমসিলিগ্রেটেড () এ, আমি নীচের উপায়ে কোড করেছিলাম:

if(viewPager.getCurrentItem() == 0) {
    FragmentClass1 frag1 = (FragmentClass1)viewPager
                            .getAdapter()
                            .instantiateItem(viewPager, viewPager.getCurrentItem());
    frag1.updateList(text); 
} else if(viewPager.getCurrentItem() == 1) {
    FragmentClass2 frag2 = (FragRecentApps)viewPager
                            .getAdapter()
                            .instantiateItem(viewPager, viewPager.getCurrentItem());
    frag2.updateList(text);
}

3
আমি মনে করি এটি সবচেয়ে সঠিক উত্তর - FragmentStatePagerAdapterকোনও কোডকে ওভাররাইড না করে ডিজাইনের সাথে সারিবদ্ধ করুন । আসলে, এটি একটি ফাংশন ঠিক ফিরে হিসাবে সহজ হতে হবে viewPager.getAdapter().instantiateItem(viewPager, viewPager.getCurrentItem())
জন পাং

39

ফ্র্যাগমেন্টস্টেটপেজারএডাপ্টারের নাম ইনস্ট্যান্টিয়েট আইটেমের সাথে সর্বজনীন পদ্ধতি রয়েছে যা নির্দিষ্ট প্যারামিটার মানের উপর ভিত্তি করে আপনার খণ্ডটি ফেরত দেয়, এই পদ্ধতিতে দুটি পরামিতি ভিউগ্রুপ (ভিউপাগার) এবং অবস্থান রয়েছে।

public Object instantiateItem(ViewGroup container, int position);

নির্দিষ্ট অবস্থানের টুকরা পেতে এই পদ্ধতিটি ব্যবহার করুন,

Fragment fragment = (Fragment) adaper.instantiateItem(mViewPager, position);

5
কিন্তু এটি বর্তমান ইতিমধ্যে ইনস্ট্যান্টেটেড টুকরাটি ফিরিয়ে দেয় না, তবে নতুন পরিবর্তে, না? এভাবে নাম "ইনস্ট্যান্টিয়েট" ...
আইএক্সএক্স

1
@ আইএক্সএক্স না এটি কোনও নতুন খণ্ড তৈরি করে না। আমি মনে করি পদ্ধতির নামটি এখানে ভুল।
বাগগুলি ঘটেছে

15

আমি এটির দেরী জানি কিন্তু এটি করার সহজ উপায় আমার কাছে রয়েছে,

// 0 সম্ভাবনা এ খণ্ড জন্য

((mFragment) viewPager.getAdapter().instantiateItem(viewPager, 0)).yourMethod();

10

এখানে প্রচুর উত্তর রয়েছে যা প্রাথমিকভাবে এটির পূর্বাভাস দেওয়ার কোন উপায় নেই এবং এই উপায়টির ফলে আপনি ভবিষ্যতে কোনও মুহুর্তে নিজেকে পায়ে গুলি করতে পারবেন না এমন সত্যিকারের মৌলিক বিষয়টিকে সত্যই সম্বোধন করে না।

FragmentStatePagerAdapterএকমাত্র শ্রেণি যা জানে যে কীভাবে নির্ভরযোগ্যভাবে সেই টুকরোগুলি অ্যাক্সেস করতে পারে যা দ্বারা ট্র্যাক করা হয় FragmentManager- খণ্ডটির আইডি বা ট্যাগ চেষ্টা করার এবং অনুমান করার যে কোনও প্রচেষ্টা নির্ভরযোগ্য, দীর্ঘমেয়াদী নয়। এবং রাষ্ট্রগুলি সংরক্ষণ / পুনরুদ্ধার করা হলে ম্যানুয়ালি উদাহরণগুলি ট্র্যাক করার চেষ্টাগুলি সম্ভবত কার্যকরভাবে কাজ করবে না, কারণ FragmentStatePagerAdapterযখন রাষ্ট্রটি পুনরুদ্ধার করা হয় তখন কলব্যাকগুলি কল করতে পারে না।

আমি যে কাজটি করতে সক্ষম হয়েছি তার সম্পর্কে হ'ল FragmentStatePagerAdapterএকটি অবস্থানের জন্য কোডটি অনুলিপি করা এবং টুকরোটি ফেরত দেওয়ার একটি পদ্ধতি যুক্ত করা mFragments.get(pos)। নোট করুন যে এই পদ্ধতিটি ধরে নিয়েছে যে খণ্ডটি প্রকৃতপক্ষে উপলব্ধ (যেমন এটি কোনও সময়ে দৃশ্যমান ছিল)।

আপনি যদি বিশেষত দুঃসাহসী হন তবে আপনি ব্যক্তিগত mFragmentsতালিকার উপাদানগুলিতে অ্যাক্সেস করতে প্রতিবিম্বটি ব্যবহার করতে পারেন , তবে তারপরে আমরা আবার এক বর্গায় ফিরে আসছি (তালিকার নাম একই থাকার নিশ্চয়তা নেই)।


1
"রাষ্ট্র যখন সংরক্ষণ / পুনরুদ্ধার করা হয় তখন ভাল কাজ করে না" এর সাথে মোকাবিলা করার জন্য, আমি পদ্ধতিটি সেভস্টেট () টি ওভাররাইড করি। যাতে পেজারার ক্রিয়াকলাপ বিরতি দেওয়া হয় তখন কোনও খণ্ড সংরক্ষণ না করে। এটা কাজ করে।
এন্টোইনপি

2
এটি কেবল অন্তর্নিহিত সমস্যাটি সমাধান না করে প্যাচওয়ার্কটিতে যুক্ত করে। আমি তর্ক করছি না যে এটি কাজ করে না - কেবল এটি কার্যকর প্রয়োগ নয়।
মেল্লওয়ার

8
getSupportFragmentManager().getFragments().get(viewPager.getCurrentItem());

আপনি যে কাজ করতে চান তার উপরের লাইন থেকে পুনরুদ্ধার করা উদাহরণটি কাস্ট করুন। পুরোপুরি সূক্ষ্ম কাজ করে।

viewPager

প্যাজার উদাহরণটি টুকরো টুকরো পরিচালনা করে।


এটি কেবল তখনই কাজ করে যদি সমস্ত পৃষ্ঠাগুলিকে খণ্ড হিসাবে লোড করা হয়। যখন উদাহরণস্বরূপ অনেকগুলি ট্যাব / পৃষ্ঠাগুলি সহ একটি ট্যাবলআউট থাকে তখন সেগুলি সমস্ত লোড হয় না, সুতরাং এটি একটি সূচকআউটবোনস ব্যতিক্রম বাড়িয়ে তুলতে পারে।
প্রগতিউবি

@ প্রোগ্রামনিবি হ্যাঁ এটির জন্য একটি অতিরিক্ত ওয়ার্কআরাউন্ড কোডের প্রয়োজন হবে।
গৌরব পানগম

@ প্রোগ্রনিউবি এভজেনির উত্তর নীচে সেই পরিস্থিতি সামাল দেবে বলে আমি মনে করি
গৌরব পাঙ্গম

7

একটি বিকল্প নির্বাচন করে, আমার বর্তমানে উপস্থিত অংশগুলিকে আপডেট করতে হবে।

বর্তমানে দৃশ্যমান খণ্ডটির রেফারেন্স পেতে, ধরে নিন যে আপনার ViewPagerহিসাবে একটি রেফারেন্স রয়েছে mPager। তারপরে নিম্নলিখিত পদক্ষেপগুলির একটি রেফারেন্স পাবেন currentFragment:

  1. PageAdapter adapter = mPager.getAdapter();
  2. int fragmentIndex = mPager.getCurrentItem();
  3. FragmentStatePagerAdapter fspa = (FragmentStatePagerAdapter)adapter;
  4. Fragment currentFragment = fspa.getItem(fragmentIndex);

শুধুমাত্র ব্যবহৃত castালাই লাইন 3 সাধারণত বৈধ। FragmentStatePagerAdapterএকটি ভিউপ্যাজারের জন্য একটি দরকারী অ্যাডাপ্টার।


7

এটি করার সর্বোত্তম উপায়, কেবল কলিংফ্রেগমেন্টনাম ফ্রেগমেন্টকে কল করুন = (কলিংফ্রেগমেন্টনাম) ভিউপেজার এটি আপনার কলিং ফ্রেগমেন্টটিকে পুনরায় ইনস্ট্যান্ট করবে, যাতে এটি নাল পয়েন্টার ব্যতিক্রম না ফেলে এবং সেই অংশের যে কোনও পদ্ধতিতে কল করে না।


6

বর্তমান খণ্ড:

আপনি যদি টুকরো টববার টেম্পলেট দিয়ে একটি প্রকল্প তৈরি করেন তবে এটি কাজ করে।

Fragment f = mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());

নোট করুন যে এটি ডিফল্ট ট্যাবড ক্রিয়াকলাপ টেম্পলেট বাস্তবায়নের সাথে কাজ করে।


30
এটি আপনার getItem () প্রয়োগের উপর নির্ভর করে - এটি খণ্ডটির একটি নতুন উদাহরণ ফিরে আসতে পারে, যা সম্ভবত আপনি চান না।
টম

এইভাবে আপনি এটি করেন। আপনি যদি টুকরো টুকরো প্রকল্পের সাথে একটি ট্যাবর তৈরি করার সময় এখনও ডিফল্ট কনফিগারেশন থাকে। কারও কাছেই এই সমাধান ছিল না। সুতরাং আমি ভেবেছিলাম এটি সাহায্য করবে।
হাসান

3

আমি নিম্নলিখিত ব্যবহার করেছি:

 int index = vpPager.getCurrentItem();
 MyPagerAdapter adapter = ((MyPagerAdapter)vpPager.getAdapter());
 MyFragment suraVersesFragment = (MyFragment)adapter.getRegisteredFragment(index);

1
এটি এখানে পাওয়া উত্তর থেকে একটি কাস্টম পেজার বাস্তবায়নের উপর নির্ভর করে: stackoverflow.com/questions/8785221/…
টম রেডম্যান

1
এটি হ'ল আমি যা করার চেষ্টা করছিলাম কিন্তু কোন পদ্ধতিগুলি ওভাররাইড করা হবে তা না জেনে ঘন্টা নষ্ট হত - ধন্যবাদ!
ব্রোন ডেভিস

2

FragmentStatePagerAdapterএকটি বেসরকারি উদাহরণস্বরূপ পরিবর্তনশীল বলা mCurrentPrimaryItemধরনের Fragment। একমাত্র আশ্চর্য হতে পারে যে অ্যান্ড্রয়েড ডিভস কেন এমন কোনও সরবরাহকারীর সাথে এটি সরবরাহ করে নি। এই পরিবর্তনশীল পদ্ধতিতে তাত্ক্ষণিক হয় setPrimaryItem()। সুতরাং, আপনার এই ভেরিয়েবলের রেফারেন্স পেতে এই পদ্ধতিটিকে এইভাবে ওভাররাইড করুন। আমি কেবল আমার নিজের ঘোষণা দিয়ে mCurrentPrimaryItemএবং setPrimaryItem()আমার ওভাররাইডে লিখিত সামগ্রীগুলি অনুলিপি করে শেষ করেছিলাম।

আপনার প্রয়োগে FragmentStatePagerAdapter:

private Fragment mCurrentPrimaryItem = null;

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
    Fragment fragment = (Fragment)object;
    if (fragment != mCurrentPrimaryItem) {
        if (mCurrentPrimaryItem != null) {
            mCurrentPrimaryItem.setMenuVisibility(false);
            mCurrentPrimaryItem.setUserVisibleHint(false);
        }
        if (fragment != null) {
            fragment.setMenuVisibility(true);
            fragment.setUserVisibleHint(true);
        }
        mCurrentPrimaryItem = fragment;
    }
}

public TasksListFragment getCurrentFragment() {
    return (YourFragment) mCurrentPrimaryItem;
}

2

আপনি এটির PagerAdapterমতো সংজ্ঞা দিতে পারেন তবে আপনি যে কোনওটি পেতে সক্ষম Fragmentহবেন ViewPager

private class PagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();

    public PagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment) {
        mFragmentList.add(fragment);
    }
}

কারেন্ট পেতে Fragment

Fragment currentFragment = mPagerAdapter.getItem(mViewPager.getCurrentItem());

2

যখন আমরা ভিউপেজারটি ব্যবহার করি তখন ক্রিয়াকলাপে খণ্ডিত দৃষ্টান্ত অ্যাক্সেস করার একটি ভাল উপায় হ'ল ইনস্ট্যান্টিয়েট আইটেম (ভিউপ্যাজার, সূচক)। // সূচী- খণ্ডের সূচক যা আপনি উদাহরণ চান।

উদাহরণস্বরূপ আমি 1 সূচক- এর টুকরো টুকরো অ্যাক্সেস করছি

Fragment fragment = (Fragment) viewPageradapter.instantiateItem(viewPager, 1);

if (fragment != null && fragment instanceof MyFragment) {      
 ((MyFragment) fragment).callYourFunction();

}

1

আমি একই সমস্যা ছিল এবং এই কোডটি ব্যবহার করে এটি সমাধান করেছি।

MyFragment fragment = (MyFragment) thisActivity.getFragmentManager().findFragmentById(R.id.container);

কেবলমাত্র আপনার খণ্ডের নামের সাথে মাইফ্রেগমেন্ট নামটি প্রতিস্থাপন করুন এবং আপনার খণ্ডের ধারকটির আইডি যুক্ত করুন।


1

এটি গ্রহণযোগ্য উত্তরের চেয়ে ভবিষ্যতের প্রমাণ:

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    /* ------------------------------------------------------------------------------------------ */
    // region Private attributes :

    private Context _context;
    private FragmentManager _fragmentManager;
    private Map<Integer, String> _fragmentsTags = new HashMap<>();

    // endregion
    /* ------------------------------------------------------------------------------------------ */



    /* ------------------------------------------------------------------------------------------ */
    // region Constructor :

    public MyFragmentPagerAdapter(Context context, FragmentManager fragmentManager) {

        super(fragmentManager);

        _context = context;
        _fragmentManager = fragmentManager;
    }

    // endregion
    /* ------------------------------------------------------------------------------------------ */



    /* ------------------------------------------------------------------------------------------ */
    // region FragmentPagerAdapter methods :

    @Override
    public int getCount() { return 2; }

    @Override
    public Fragment getItem(int position) {

        if(_fragmentsTags.containsKey(position)) {

            return _fragmentManager.findFragmentByTag(_fragmentsTags.get(position));
        }
        else {

            switch (position) {

                case 0 : { return Fragment.instantiate(_context, Tab1Fragment.class.getName()); }
                case 1 : { return Fragment.instantiate(_context, Tab2Fragment.class.getName()); }
            }
        }

        return null;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {

        // Instantiate the fragment and get its tag :
        Fragment result = (Fragment) super.instantiateItem(container, position);
        _fragmentsTags.put(position, result.getTag());

        return result;
    }

    // endregion
    /* ------------------------------------------------------------------------------------------ */
}

পরিবর্তে আপনার WeakHashMap ব্যবহার করা উচিত।
প্রকাশ নাদার 22'17

1

প্রশ্নে দৃশ্যকল্প ভাল বর্ণনা অনুযায়ী, প্রতিটি অংশ তার নিজস্ব মেনু আইটেম যুক্ত করা এবং সরাসরি onOptionsItemSelected হ্যান্ডলিং () দ্বারা পরিবেশিত হয় সরকারী ডকুমেন্টেশন । অননুমোদিত কৌশলগুলি এড়ানো ভাল।


এই উত্তরটি কীভাবে আসলে তা করতে পারে তার জন্য আরও বিশদ ব্যবহার করতে পারে। কীভাবে মেনু আইটেম যুক্ত করা ViewPagerসমস্যার সমাধান করে ?
সুরগাচ

@ সুরগ ভিউপেজার সমস্যাটি উপস্থিত রয়েছে যদি মেনু ইভেন্টগুলিকে ক্রিয়াকলাপের মধ্যে পরিচালনা করা হয় যা খণ্ডগুলিকে হোস্ট করে এবং যদি ইভেন্টগুলি খণ্ডের মধ্যেই পরিচালনা করা হয় তবে তা উপস্থিত না থাকে। লিঙ্কটি দেখায় যে কোনও খণ্ড কীভাবে তার নিজস্ব মেনু আইটেম যুক্ত করতে পারে।
Y2i

1

সমস্ত মন্তব্য এবং উত্তর পড়ার পরে আমি এই সমস্যার একটি অনুকূল সমাধান ব্যাখ্যা করতে যাচ্ছি। সেরা বিকল্পটি হ'ল @ রিকের সমাধান, সুতরাং আমার উন্নতি তার ভিত্তিতে।

পরিবর্তে প্রতিটি ফ্রেগমেন্ট ক্লাস জিজ্ঞাসা না করে

if(FragmentClass1){
   ...
if(FragmentClass2){
   ...
}

আপনার নিজস্ব ইন্টারফেস তৈরি করুন এবং আপনার সন্তানের টুকরো তৈরি করুন, এরকম কিছু

public interface MyChildFragment {
    void updateView(int position);
}

তারপরে, আপনি নিজের অভ্যন্তরের টুকরোগুলি শুরু এবং আপডেট করতে এর মতো কিছু করতে পারেন।

Fragment childFragment = (Fragment) mViewPagerDetailsAdapter.instantiateItem(mViewPager,mViewPager.getCurrentItem());

if (childFragment != null) {
   ((MyChildFragment) childFragment).updateView();
}

পিএস আপনি এই কোডটি কোথায় রেখেছেন সে বিষয়ে সতর্ক থাকুন, সিস্টেমটি তৈরি করার আগে আপনি যদি ক্ষুধা আইটেমটি কল করেন তবে savedInstanceStateআপনার সন্তানের খণ্ডটি এর জন্য বাতিল হয়ে যাবে

public void onCreate(@Nullable Bundle savedInstanceState){
      super(savedInstanceState)
}

আপনার অ্যাপ্লিকেশন ক্রাশ হবে।

শুভকামনা


1

তিনি কি উত্তর দিয়েছেন উপর ভিত্তি করে @ ছাহাট জেইন:

"যখন আমরা ভিউপেজারটি ব্যবহার করি তখন ক্রিয়াকলাপে খণ্ডের উদাহরণটি অ্যাক্সেস করার একটি ভাল উপায় হ'ল ইনস্ট্যান্টিয়েট আইটেম (ভিউপ্যাজার, সূচক) // // সূচি-সূচী আপনি যে অংশটি চান তা সূচী।"

যদি আপনি কোটলিনে এটি করতে চান

val fragment =  mv_viewpager.adapter!!.instantiateItem(mv_viewpager, 0) as Fragment
                if ( fragment is YourFragmentFragment)
                 {
                    //DO somthign 
                 }

0 এর টুকরো টুকরো 0

// ================================================ ======================== // // ######################## ######## # ব্যবহারের উদাহরণ ################################## // // == ================================================== ===================== //

সম্পর্কে একটি হারানো দৃষ্টি পেতে এখানে একটি সম্পূর্ণ উদাহরণ

.xML ফাইলটিতে আমার ভিউপেজারটি এখানে

   ...
    <android.support.v4.view.ViewPager
                android:id="@+id/mv_viewpager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"/>
    ...

এবং হোম ক্রিয়াকলাপ যেখানে আমি ট্যাবটি সন্নিবেশ করিয়েছি

...
import kotlinx.android.synthetic.main.movie_tab.*

class HomeActivity : AppCompatActivity() {

    lateinit var  adapter:HomeTabPagerAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
       ...
    }



    override fun onCreateOptionsMenu(menu: Menu) :Boolean{
            ...

        mSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
          ...

            override fun onQueryTextChange(newText: String): Boolean {

                if (mv_viewpager.currentItem  ==0)
                {
                    val fragment =  mv_viewpager.adapter!!.instantiateItem(mv_viewpager, 0) as Fragment
                    if ( fragment is ListMoviesFragment)
                        fragment.onQueryTextChange(newText)
                }
                else
                {
                    val fragment =  mv_viewpager.adapter!!.instantiateItem(mv_viewpager, 1) as Fragment
                    if ( fragment is ListShowFragment)
                        fragment.onQueryTextChange(newText)
                }
                return true
            }
        })
        return super.onCreateOptionsMenu(menu)
    }
        ...

}

1

আমার পূর্ববর্তী প্রয়োগে আমি শিশু খণ্ডগুলির পরে সেগুলিতে অ্যাক্সেস করতে সক্ষম হওয়ার একটি তালিকা সঞ্চয় করেছিলাম তবে এটি একটি ভুল বাস্তবায়ন হয়ে দাঁড়ায় যাতে বিশাল মেমরি ফাঁস হয়।

আমি instantiateItem(...)বর্তমান টুকরাটি পেতে পদ্ধতি ব্যবহার করে শেষ করেছি :

val currentFragment = adapter?.instantiateItem(viewPager, viewPager.currentItem)

অথবা পজিশনে অন্য কোনও অংশ পেতে:

val position = 0
val myFirstFragment: MyFragment? = (adapter?.instantiateItem(viewPager, position) as? MyFragment)

ডকুমেন্টেশন থেকে :

প্রদত্ত অবস্থানের জন্য পৃষ্ঠা তৈরি করুন। অ্যাডাপ্টারটি এখানে প্রদত্ত ধারকটিতে ভিউ যুক্ত করার জন্য দায়ী, যদিও এটি কেবলমাত্র ফিনিশআপডেট (ভিউগ্রুপ) থেকে ফিরে আসার পরে এটি সম্পন্ন করা নিশ্চিত করতে হবে।


0

আমার ক্রিয়াকলাপে আমি:

int currentPage = 0;//start at the first tab
private SparseArray<Fragment> fragments;//list off fragments
viewPager.setOnPageChangeListener(new OnPageChangeListener() {

@Override
public void onPageSelected(int pos) {
        currentPage = pos;//update current page
}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {}
@Override
public void onPageScrollStateChanged(int arg0) {}
});



@Override
public void onAttachFragment(Fragment fragment) {
    super.onAttachFragment(fragment);
    if(fragment instanceof Fragment1)
        fragments.put(0, fragment);
    if(fragment instanceof Fragment2)
        fragments.put(2, fragment);
    if(fragment instanceof Fragment3)
        fragments.put(3, fragment);
    if(fragment instanceof Fragment4)
        fragments.put(4, fragment);
}

Then I have the following method for getting the current fragment

public Fragment getCurrentFragment() {
    return fragments.get(currentPage);
}

0
final ViewPager.OnPageChangeListener onPageChangeListener =
    new ViewPager.OnPageChangeListener() {
      @Override public void onPageSelected(int position) {
        switch (position) {
          case 0:
            FragmentClass1 frag1 =
                (FragmentClass1) viewPager.getAdapter()
                    .instantiateItem(viewPager, viewPager.getCurrentItem());
            frag1.updateList("Custom text");
            break;
          case 1:
            break;
          case 2:
            break;
        }
      }

      @Override
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

      }

      @Override public void onPageScrollStateChanged(int state) {
      }
    };


 viewPager.addOnPageChangeListener(onPageChangeListener);

viewPager.setAdapter(adapter);


viewPager.post(new Runnable() {
  @Override public void run() {
    onPageChangeListener.onPageSelected(viewPager.getCurrentItem());
  }
});

কখনও কখনও খণ্ডটি একটি নাল বস্তু প্রেরণ করতে পারে, তাই আপনি প্রথম লোডে সমস্যাটি সমাধান করার জন্য একটি নতুন রান্নেবল চালাতে পারেন।

ধন্যবাদ রিক


এই কোডটি কেন ওপির সমস্যার সমাধান করবে তা বোঝাতে দয়া করে কিছু পাঠ্য যুক্ত করুন। এছাড়াও, আরও কতগুলি উত্তর রয়েছে তা প্রদত্ত, ইতিমধ্যে প্রদত্ত উত্তরগুলির চেয়ে এই উত্তর কেন ভাল তা ব্যাখ্যা করুন। অন্যদের বুঝতে সাহায্য করুন।
এপিসি

0

আপনার ফ্র্যাগমেন্ট পেজারএডাপ্টার থেকে সেটপ্রাইমারি আইটেমটি ওভাররাইড করুন: অবজেক্টটি দৃশ্যমান খণ্ড:

 @Override
        public void setPrimaryItem(ViewGroup container, int position, Object object) {
            if (mCurrentFragment != object) {
                mCurrentFragment = (LeggiCapitoloFragment) object;
            }
            super.setPrimaryItem(container, position, object);
        }

0

পেজার থেকে কেবল বর্তমান আইটেমটি পান এবং তারপরে আপনার অ্যাডাপ্টারটিকে সেই অবস্থানের টুকরোতে জিজ্ঞাসা করুন।

 int currentItem = viewPager.getCurrentItem();
    Fragment item = mPagerAdapter.getItem(currentItem);
    if (null != item && item.isVisible()) {
       //do whatever want to do with fragment after doing type checking
        return;
    }

3
getItemএকটি নতুন উদাহরণ তৈরি করলে কী হবে
প্রকাশ নাদার

0

বর্তমান খণ্ডটি পেতে - ভিউপাগারে পজিশনের শূন্যপানেপেজ নির্বাচন করা (চূড়ান্ত অভ্যন্তরীণ অবস্থান) এ অবস্থান পান এবং তারপরে

public PlaceholderFragment getFragmentByPosition(Integer pos){
    for(Fragment f:getChildFragmentManager().getFragments()){
        if(f.getId()==R.viewpager && f.getArguments().getInt("SECTNUM") - 1 == pos) {
            return (PlaceholderFragment) f;
        }
    }
    return null;
}

SECTNUM - পাবলিক স্ট্যাটিক প্লেসহোল্ডারফ্র্যাগমেন্ট নিউ ইনস্ট্যান্স (ইন বিভাগে নম্বর) এ নিয়োগের অবস্থানের আর্গুমেন্ট ; খণ্ডের

getChildFraamentManager () বা getFragmentManager () - কীভাবে তৈরি করা হয়েছে বিভাগগুলি PagerAdapter উপর নির্ভর করে


0

আপনি খণ্ডে একটি ব্রডকাস্টার্সিভার কার্যকর করতে এবং যে কোনও জায়গা থেকে একটি উদ্দেশ্য প্রেরণ করতে পারেন। খণ্ডটির প্রাপক নির্দিষ্ট ক্রিয়াকলাপ শুনতে এবং উদাহরণের পদ্ধতির জন্য প্রার্থনা করতে পারে।

একটি সতর্কতা নিশ্চিত করছে যে ভিউ উপাদানটি ইতিমধ্যে ইনস্ট্যান্ট হয়েছে এবং (এবং কিছু ক্রিয়াকলাপের জন্য, যেমন একটি তালিকা স্ক্রোলিংয়ের জন্য তালিকা ভিউ ইতিমধ্যে রেন্ডার করা উচিত)।


0

এটি সহজ হ্যাক:

fun getCurrentFragment(): Fragment? {
    return if (count == 0) null
    else instantiateItem(view_pager, view_pager.currentItem) as? Fragment
}

(কোটলিন কোড)

শুধু কল করে instantiateItem(viewPager, viewPager.getCurrentItem()এটিকে কাস্ট করুন Fragment। আপনার আইটেম ইতিমধ্যে ইনস্ট্যান্ট করা হবে। আপনি চেক যোগ করতে পারেন তা নিশ্চিত হওয়ার জন্য getCount

উভয় সঙ্গে কাজ করে FragmentPagerAdapterএবং FragmentStatePagerAdapter!


0

আপনার পেজার যদি কোনও খণ্ডের ভিতরে থাকে তবে এটি ব্যবহার করুন:

private fun getPagerCurrentFragment(): Fragment? {
    return childFragmentManager.findFragmentByTag("android:switcher:${R.id.myViewPagerId}:${myViewPager.currentItem}")
}

কোথায় R.id.myViewPagerIdXML বিন্যাস ভিতরে আপনার ViewPager ID।


এটি কেবলমাত্র ফ্র্যাগমেন্ট পেজএডাপ্টার দিয়ে কাজ করে না ফ্রেগমেন্টস্টেটপেজএডাপ্টারের সাথে নয়।
প্রগতিউবি

0

আপনি নিবন্ধের টুকরো হিসাবে খণ্ডের একটি অ্যারে ঘোষণা করতে পারেন

class DashboardPagerAdapter(fm: FragmentManager?) : FragmentStatePagerAdapter(fm!!) {
    // CURRENT FRAGMENT
    val registeredFragments = SparseArray<Fragment>()

    override fun instantiateItem(container: ViewGroup, position: Int): Any {
        val fragment = super.instantiateItem(container, position) as Fragment
        registeredFragments.put(position, fragment)
        return fragment
    }

    override fun getItem(position: Int): Fragment {
        return when (position) {
            0 -> HomeFragment.newInstance()
            1 -> ConverterDashboardFragment.newInstance()
            2 -> CartFragment.newInstance()
            3 -> CustomerSupportFragment.newInstance()
            4 -> ProfileFragment.newInstance()
            else -> ProfileFragment.newInstance()
        }
    }

    override fun getCount(): Int {
        return 5
    }

}

তারপরে আপনি এটি হিসাবে ব্যবহার করতে পারেন

adapter?.let {
    val cartFragment = it.registeredFragments[2] as CartFragment?
    cartFragment?.myCartApi(true)
}

আপনি যদি সেই পথে যাওয়ার সিদ্ধান্ত নেন তবে আপনার ডিস্টোন আইটেম () প্রয়োগ করতে হবে এবং নিবন্ধিত অংশগুলি থেকে ধ্বংস হওয়া দুরত্ব সরিয়ে ফেলতে হবে, অন্যথায় আপনার স্মৃতি ফাঁস হবে।
ডিফাইনরা

এটা ভাল পরামর্শ। উত্তরে একটি সম্পাদনা করতে আপনাকে স্বাগতম।
হামজা খান

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.