ViewPager.setOffscreenPageLimit (0) প্রত্যাশার মতো কাজ করে না


100

আমার ViewPagerউদাহরণে আমি যে টুকরোগুলি ব্যবহার করি তা হ'ল সম্পদ নিবিড়, সুতরাং আমি কেবল একবারে একটি লোড করতে চাই। আমি যখন নিম্নলিখিতটি চেষ্টা করি:

mViewPager.setOffscreenPageLimit(0);
mViewPager.setAdapter(mPagerAdapter);

আমার FragmentStatePagerAdapter.getItem(int position)ওভাররাইড ফাংশনটি 3 বার বলা হয়, যা আমি কল করি তখনই ঘটে mViewPager.setOffscreenPageLimit(1)। আমি এটি কেবল একবার কল করার আশা করব, কারণ আমি 0 টি স্ক্রিন পৃষ্ঠা উল্লেখ করেছি।

আমি বিশ্বাস করি আমি সঠিকভাবে যদি আমি কল কারণ সবকিছুই ফোন করেছি mViewPager.setOffscreenPageLimit(2), FragmentStatePagerAdapter.getItem(int position)5 বার বলা হয় হিসাবে আমি আশা করবে।

ভিউপ্যাজারের কি সর্বনিম্ন ১ টি অফস্ক্রিন পৃষ্ঠা প্রয়োজন, বা আমি এখানে কিছু ভুল করছি?


9
আমি একটি বৈশিষ্ট্য অনুরোধ যুক্ত করেছি: কোড. google.com/p/android/issues/detail?id=56667
চিহ্নিত করুন


আমার কাছে মাত্র 3 টি ট্যাব এবং সেটিং ViewPager.setOffscreenPageLimit(2)আমার জন্য কাজ করেছিল। চেষ্টা করুনViewPager.setOffscreenPageLimit(totTabs - 1)
sibin

উত্তর:


112

ভিউপ্যাজারের জন্য কি সর্বনিম্ন ১ টি অফস্ক্রিন পৃষ্ঠা প্রয়োজন?

হ্যাঁ. যদি আমি উত্স কোডটি সঠিকভাবে পড়ছি, আপনি লগকেটে এই সম্পর্কে একটি সতর্কতা পেয়ে যাবেন:

Requested offscreen page limit 0 too small; defaulting to 1

6
এটি কোনও সমাধান নয়! আমি কেবল 1 টি টুকরো লোড করতে চাই না 2 এটি অবশ্যই কোনওভাবে সম্ভব?
এইচজিবিবি

14
@ হারাল্ডো: "নিশ্চয়ই এটি কোনওভাবে সম্ভব?" - সাথে না ViewPagerViewPagerএই টুকরোগুলি তৈরি করে যাতে দর্শনগুলি বিদ্যমান থাকে, তাই ব্যবহারকারীরা এনিমেটেড এফেক্ট সহ পুরানো ভিউটি স্ক্রিন থেকে সরে যাওয়া এবং নতুন ভিউটি স্ক্রিনে স্লাইড করে দেখায় them আপনার নিজের লেখার চেষ্টা করার জন্য আপনাকে স্বাগত জানাই ViewPagerযা অস্তিত্বহীন জিনিসগুলির মধ্যে সোয়াইপ করতে পারে। আপনি এ সম্পর্কে আরও জানতে কোড. google.com/p/android/issues/detail?id=56667#c3
CommonsWare

2
হ্যাঁ, আমি এই সংখ্যাটি পড়েছি। শুধু যৌক্তিক নয়। আমি setOffscreenPageLimit(0)০. তে সক্ষম হব বলে আশা করি তারপরে আমি নিজেই পরিণতিগুলি মোকাবিলা করতে পারি। একটি খণ্ড খণ্ড লোড না হওয়া পর্যন্ত একটি ডিফল্ট খালি খণ্ড উদাহরণস্বরূপ স্থানধারক হতে পারে। যার সবগুলি ইউআই থ্রেডের বাইরে চলে যেতে পারে। যাই হোক আমি এ নিয়ে খুব একটা ভাবিনি।
এইচজিবিবি

5
@ হারাল্ডো: "একটি খালি খণ্ডটি লোড না হওয়া পর্যন্ত উদাহরণস্বরূপ একটি স্থানধারক হতে পারে" - আপনার বিদ্যমান অংশীদারিত্বের সাথে আজ আপনার খণ্ডে কোনও স্থানধারককে আপনাকে স্বাগত জানানো হবে, এটি ViewPagerউপলব্ধ হলে সত্যিকারের সামগ্রী দিয়ে প্রতিস্থাপন করবে ।
কমন্সওয়্যার

2
onPageChangeListener সমাধান মত মনে হচ্ছে।
এলিকানবাতুর

123

আমি খুঁজে পেয়েছি সেরা উপায় setUserVisibleHint এটি
আপনার খণ্ডে যুক্ত করুন

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        // load data here
    }else{
       // fragment is no longer visible
    }
}

1
এই সমাধানের জন্য +++++ !!! ধন্যবাদ, এই কোডটি যুক্ত করার পরে আমি প্রথমবারের মতো এনপিএল পেয়েছি, আমি কেবল চেষ্টা করে ব্লক যুক্ত করেছি এবং এর কাজগুলি আমার জন্য নিখুঁত !!!
ভাভিন চৌহান

1
এটি ব্যবহার করার পরে এটি দ্বিতীয় ভিউপেজার খণ্ডে তৃতীয় খণ্ডের লোডিং ডেটা দ্বিতীয় ভাগে তারিখটি লোড করে না। কেউ আমাকে সাহায্য করতে পারেন?
আরশাদ

আমি কি কিছু মিস করছি, ক্রেইটভিউয়ের আগে সেটউজারভিজিবলহিন্ট কল করা হয়েছে
আন্তন

সেরা সমাধানটি এখন
অবনমিত করা

@ এমসিরের সেট ইউজারভিজিবিলহিন্টের বিকল্প কি ভুল?
যুদি কর্মফল

8

আপনি এটির মতো চেষ্টা করতে পারেন:

public abstract class LazyFragment extends Fragment {
    protected boolean isVisible;
    /**
     * 在这里实现Fragment数据的缓加载.
     * @param isVisibleToUser
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(getUserVisibleHint()) {
            isVisible = true;
            onVisible();
        } else {
            isVisible = false;
            onInvisible();
        }
    }
    protected void onVisible(){
        lazyLoad();
    }
    protected abstract void lazyLoad();
    protected void onInvisible(){}

protected abstract void lazyLoad();
protected void onInvisible(){}

যে সেরা উত্তর!
রাদেশ

7

প্রথম অ্যাড

   boolean isFragmentLoaded = false;

চেয়ে

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser && !isFragmentLoaded) {
        //Load Your Data Here like.... new GetContacts().execute();

        isFragmentLoaded = true;
    }
else{
     }
}

6
তবে এই পদ্ধতিটি অনক্রিটভিউ
জার ই আহমের

2

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


1

এটি পুরানো থ্রেড হতে পারে তবে এটি আমার পক্ষে কাজ করে বলে মনে হচ্ছে। এই ফাংশনটি ওভাররাইড করুন:

@Override
public void setMenuVisibility(boolean menuVisible) { 
    super.setMenuVisibility(menuVisible);

    if ( menuVisible ) {
        /**
         * Load your stuffs here.
         */
    } else  { 
        /**
         * Fragment not currently Visible.
         */
    } 
}

শুভ কোডিং ...


ওয়েবভিউতে কী আছে? আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি এটির জন্য একটি নতুন থ্রেড তৈরি করুন।
রাল্ফগ্যাব

1

আমার ক্ষেত্রে আমি দৃশ্যে কিছু অ্যানিমেশন শুরু করতে চেয়েছিলাম, কিন্তু সেট ইউজারভিজিবলহিন্টের সাথে কিছু সমস্যা পেয়েছে ...
আমার সমাধানটি হ'ল:

আপনার অ্যাডাপ্টারের জন্য 1 / addOnPageChangeListener:

mViewPager.addOnPageChangeListener(this);

2 / অনপেজ চ্যাঞ্জলিস্টনার প্রয়োগ করুন:

public class PagesFragment extends Fragment implements ViewPager.OnPageChangeListener

3/3 টি পদ্ধতিতে ওভাররাইড করুন:

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

}

@Override
public void onPageSelected(int position)
{ 
}

@Override
public void onPageScrollStateChanged(int state)
{
}

4 / আপনার ক্লাসে এই পরিবর্তনশীল ডিক্লেয়ার এবং আরম্ভ করুন

private static int mTabState = 1;

বিজ্ঞপ্তি : আমার আমার অ্যাডাপ্টারে তিনটি টুকরা রয়েছে, এবং সেটক্রেনার আইটেম এবং অ্যাডাপ্টারের বর্তমান অবস্থানের জন্য এমট্যাবস্টেট ব্যবহার করি যা সনাক্ত করে কোন ফাংশনটি সময়মতো ব্যবহারকারীকে দেখানো হয় ... 5 / অনপেজ নির্বাচিত পদ্ধতিতে এই কোডগুলি যুক্ত করুন:

if (mTabState == 0 || position == 0)
    {
        Intent intent = new Intent("animation");
        intent.putExtra("current_position", position);
        LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
    }

পূর্ববর্তী পৃষ্ঠা বা বর্তমান পৃষ্ঠাটি যদি পৃষ্ঠা 0 হয় (0 অবস্থানের মধ্যে টুকরা) তবে এই জিনিসটি করুন do

6 / এখন আপনার খণ্ড শ্রেণিতে (অ্যাডাপ্টারের 0 অবস্থানে টুকরো টুকরো), আপনাকে অবশ্যই সম্প্রচারের রিসিভার তৈরি করতে হবে এবং এটি অনারুম পদ্ধতিতে নিবন্ধন করতে হবে এবং এটি অনিয়ন্ত্রিত করুন on methos:

BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        if (Objects.equals(intent.getAction(), "animation"))
        {
            int currentPosition = intent.getIntExtra("current_position", 0);
            if (currentPosition == 0)
            {
                startAnimation();
                setViewsVisible();
            } else
            {
                setViewsInvisible();
            }
        }
    }
};

@Override
public void onResume()
{
    super.onResume();
    LocalBroadcastManager.getInstance(mContext).registerReceiver(broadcastReceiver, new IntentFilter("animation"));
}

@Override
public void onPause()
{
    super.onPause();
    LocalBroadcastManager.getInstance(mContext).unregisterReceiver(broadcastReceiver);
}

সংক্ষিপ্তসার: আমার কাছে ফ্রেগমেন্ট পেজার অ্যাডাপ্টার জাদুকরীটিতে এর মধ্যে তিনটি টুকরোগুলি রয়েছে, আমি অ্যাডাপ্টারের পজিশন 0-এ ফ্রেগমেন্টে ভিউগুলিতে কিছু অ্যানিমেশন দেখাতে চাই, এর জন্য আমি ব্রডকাস্টআরসিভার ব্যবহার করি। যখন খণ্ডটি বাছাই করা হয় আমি অ্যানিমেশন পদ্ধতি শুরু করি এবং ব্যবহারকারীর দর্শন দেখায়, যখন খণ্ড যখন ব্যবহারকারীকে দেখায় না তখন আমি অদৃশ্য দৃশ্যের চেষ্টা করি ...


1

ভিউপ্যাজারে রিফ্রেশ ভিউয়ের সমাধানের জন্য দয়া করে এই কোডটি ব্যবহার করে দেখুন ...

/* DO NOT FORGET! The ViewPager requires at least “1” minimum OffscreenPageLimit */
int limit = (mAdapter.getCount() > 1 ? mAdapter.getCount() - 1 : 1);
mViewPager.setOffscreenPageLimit(limit);

0

"ইনস্ট্যান্টিয়েট আইটেম" ফাংশনের জন্য কেবল খণ্ডটি প্রস্তুত করুন, তবে ভারী সামগ্রী লোড করবেন না।

"OnPageChangeListener" ব্যবহার করুন, যাতে প্রতিবার আপনি একটি নির্দিষ্ট পৃষ্ঠায় যান, আপনি এটির ভারী সামগ্রী লোড করুন এবং এটি দেখান।


0

আমার ধরণের সমস্যা একই রকম। আমি এই সাইটে কিছু দরকারী কোড পেয়েছি এবং এটি রূপান্তর করেছি।

MViewPager.setOffscreenPageLimit (...) এর জন্য মিনিট ইনট; 1 হয়, তাই আপনি এটিকে 0 এ পরিবর্তন করলেও আপনার এখনও দুটি পৃষ্ঠা লোড হবে।

প্রথমে একটি স্ট্যাটিক ইনট তৈরি করা হয় আমরা ম্যাক্সপেজকাউন্টকে কল করব এবং ম্যাকপেজকউন্টটি ফেরত দিতে ফ্রেগমেন্টস্টেটপাগারএডাপ্টার পদ্ধতি getCount () উপস্থাপন করব:

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

এরপরে প্রোগ্রামে যে কোনও জায়গা থেকে অ্যাক্সেসযোগ্য একটি স্থিতিশীল পদ্ধতি তৈরি করুন যা আপনাকে এই সর্বোচ্চ অ্যাকাউন্টটি পরিবর্তন করতে দেয়:

public static void addPage(){
    maxPageCount++; //or maxPageCount = fragmentPosition+2
    mFragmentStatePagerAdapter.notifyDataSetChanged(); //notifyDataSetChanged is important here.
}

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

আশা করি এটি কারও সাহায্য করবে।


0

ব্যক্তিগত // বুলিয়ান ডেটা আনার জন্য এই // বুলিয়ান তৈরি করুন ব্যবহার করুনভিউশাউন = মিথ্যা;

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (getView() != null) {
        isViewShown = true;
        // fetchdata() contains logic to show data when page is selected mostly asynctask to fill the data
        fetchData();
    } else {
        isViewShown = false;
    }
} 
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.