গতিশীলভাবে ভিউপ্যাজার আপডেট করবেন?


316

আমি ভিউপিজারে সামগ্রী আপডেট করতে পারি না।

ফ্র্যাগমেন্টপেজারএডাপ্টার ক্লাসে ইনস্ট্যান্টিয়েট আইটেম () এবং গেটআইটেম () এর সঠিক ব্যবহার কী?

আমি আমার টুকরোগুলি তাত্ক্ষণিকভাবে ফিরিয়ে আনতে কেবল getItem () ব্যবহার করছিলাম:

@Override
public Fragment getItem(int position) {
    return new MyFragment(context, paramters);
}

এটি ভাল কাজ করেছে। ব্যতীত আমি সামগ্রীটি পরিবর্তন করতে পারি না।

সুতরাং আমি এটি পেয়েছি: ভিউপেজার পেজারআডাপ্টার ভিউটি আপডেট করছে না

"ইনস্ট্যান্ট আইটেম () পদ্ধতিতে যে কোনও তাত্ক্ষণিক দৃষ্টিভঙ্গির জন্য সেটট্যাগ () পদ্ধতিটি ব্যবহার করা আমার পদ্ধতি approach

এখন আমি এটি করতে ইনস্ট্যান্টিয়েট আইটেম () প্রয়োগ করতে চাই। তবে আমি জানি না আমাকে কী ফিরতে হবে (টাইপটি অবজেক্ট) এবং গেটআইটেম (ইনট পজিশন) এর সাথে কী সম্পর্ক?

আমি রেফারেন্স পড়ি :

  • পাবলিক অ্যাবস্ট্রাক্ট টুকরো টুকরো

    নির্দিষ্ট অবস্থানের সাথে যুক্ত খণ্ডটি ফেরত দিন।

  • সর্বজনীন অবজেক্ট ইনস্ট্যান্টিয়েট আইটেম (ভিউ গ্রুপের ধারক, অন্তর্নিহিত অবস্থান)

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

    ধারকযুক্ত পৃষ্ঠাটি দেখানো হবে এমন ধারণাগুলি সহ। অবস্থান পৃষ্ঠা অবস্থান তাত্ক্ষণিকভাবে করা হবে।

    রিটার্নস

    নতুন পৃষ্ঠাটি উপস্থাপন করে এমন একটি বস্তু প্রদান করে। এটি দেখার প্রয়োজন হবে না, তবে পৃষ্ঠার অন্য কোনও ধারক হতে পারে।

কিন্তু আমি এখনও এটি না।

আমার কোড এখানে। আমি সমর্থন প্যাকেজ ভি 4 ব্যবহার করছি।

ViewPagerTest

public class ViewPagerTest extends FragmentActivity {
    private ViewPager pager;
    private MyFragmentAdapter adapter; 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pager1);

        pager = (ViewPager)findViewById(R.id.slider);

        String[] data = {"page1", "page2", "page3", "page4", "page5", "page6"};

        adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
        pager.setAdapter(adapter);

        ((Button)findViewById(R.id.button)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                reload();
            }
        });
    }

    private void reload() {
        String[] data = {"changed1", "changed2", "changed3", "changed4", "changed5", "changed6"};
        //adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
        adapter.setData(data);
        adapter.notifyDataSetChanged();
        pager.invalidate();

        //pager.setCurrentItem(0);
    }
}

MyFragmentAdapter

class MyFragmentAdapter extends FragmentPagerAdapter {
    private int slideCount;
    private Context context;
    private String[] data;

    public MyFragmentAdapter(FragmentManager fm, int slideCount, Context context, String[] data) {
        super(fm);
        this.slideCount = slideCount;
        this.context = context;
        this.data = data;
    }

    @Override
    public Fragment getItem(int position) {
        return new MyFragment(data[position], context);
    }

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

    public void setData(String[] data) {
        this.data = data;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

MyFragment

public final class MyFragment extends Fragment {
    private String text;

    public MyFragment(String text, Context context) {
        this.text = text;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.slide, null);
        ((TextView)view.findViewById(R.id.text)).setText(text);

        return view;
    }
}

এখানেও কেউ একই সমস্যা রয়েছে, কোনও উত্তর নেই http://www.mail-archive.com/android-developers@googlegroups.com/msg200477.html


জড়িত উপাদানগুলির আরও ভাল বোঝার জন্য এটি পৃথক পিছনের নেভিগেশন ইতিহাসের সাথে একটি ট্যাবড ভিউপ্যাজার সম্পর্কে আমার টিউটোরিয়ালটি পড়তে সহায়তা করতে পারে। : এটা GitHub এবং অতিরিক্ত সামগ্রী একটি কাজ উদাহরণস্বরূপ দিয়ে আসে medium.com/@nilan/...
marktani

কিছু ইস্যু পেয়েছে স্ট্যাকওভারফ্লো.com
অ্যালবার্ট

আপনি এই উদাহরণটি গিটহাবটিতে দেখতে পারেন । আমি আশা করি এই উদাহরণটি আপনাকে সহায়তা করবে।
ক্যাবেজাস

ভাল সহজ সমাধান: stackoverflow.com/a/35450575/2162226
জিন বো

গুগল সম্প্রতি ভিউপেজার 2 চালু করেছে যা গতিশীল খণ্ড / ভিউ আপডেটগুলি সহজ করে। আপনি exemples দেখতে পারেন github.com/googlesamples/android-viewpager2 বা এই উত্তর stackoverflow.com/a/57393414/1333448
ইভস Delerm

উত্তর:


605

ফ্রেগমেন্টপেইজারএডাপ্টার বা ফ্রেগমেন্টস্টেটপেজার অ্যাডাপ্টার ব্যবহার করার সময়, সম্পূর্ণরূপে ডিল করা getItem()এবং একেবারে স্পর্শ না instantiateItem()করা ভাল। instantiateItem()- destroyItem()- isViewFromObject()PagerAdapter ইন্টারফেস একটি নিম্ন স্তরের ইন্টারফেসে যে FragmentPagerAdapter ব্যবহারসমূহ অনেক সহজ বাস্তবায়ন হয় getItem()ইন্টারফেস।

এটি gettingোকার আগে আমার স্পষ্ট করা উচিত

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

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

আপনি লিঙ্ক করেছেন এমন পোস্টে সরবরাহ করা setTag()এবং findViewWithTag()কর্মক্ষেত্রের প্রস্তাব দিচ্ছি না । আপনি যেমন আবিষ্কার করেছেন, ব্যবহার করে setTag()এবং findViewWithTag()টুকরো টুকরো করে কাজ করে না, তাই এটি কোনও ভাল মিল নয়।

সঠিক সমাধানটি ওভাররাইড করা getItemPosition()। যখন notifyDataSetChanged()ডাকা হয়, ভিউপ্যাজার getItemPosition()তার অ্যাডাপ্টারের সমস্ত আইটেমগুলিতে কল করে যে তাদের আলাদা অবস্থানে স্থানান্তরিত করা বা অপসারণ করা প্রয়োজন কিনা তা দেখার জন্য calls

ডিফল্টরূপে, getItemPosition()রিটার্ন POSITION_UNCHANGED, যার অর্থ, "এই বস্তুটি যেখানে রয়েছে ঠিক আছে, এটি ধ্বংস বা অপসারণ করবেন না।" প্রত্যাবর্তন POSITION_NONEসমস্যাটির পরিবর্তে এই সমস্যাটি সংশোধন করে বলে, "এই বস্তুটি আমি আর প্রদর্শিত আইটেম নেই, এটি মুছে ফেলুন।" সুতরাং এটি আপনার অ্যাডাপ্টারের প্রতিটি আইটেম অপসারণ এবং পুনরায় তৈরি করার প্রভাব ফেলেছে।

এটি সম্পূর্ণ বৈধ ফিক্স! এই ফিক্সটি notifDataSetChanged দেখার জন্য পুনর্ব্যবহারযোগ্য ছাড়াই নিয়মিত অ্যাডাপ্টারের মতো আচরণ করে। আপনি যদি এই ফিক্সটি কার্যকর করেন এবং কার্য সম্পাদন সন্তোষজনক হয় তবে আপনি ঘোড়দৌড়ের বাইরে চলে যাবেন। কাজ শেষ.

আপনার যদি আরও ভাল পারফরম্যান্সের প্রয়োজন হয় তবে আপনি একটি ফ্যানসিয়ার getItemPosition()বাস্তবায়ন ব্যবহার করতে পারেন । এখানে পেজারের উদাহরণস্বরূপ স্ট্রিংগুলির তালিকার বাইরে টুকরো তৈরি করা:

ViewPager pager = /* get my ViewPager */;
// assume this actually has stuff in it
final ArrayList<String> titles = new ArrayList<String>();

FragmentManager fm = getSupportFragmentManager();
pager.setAdapter(new FragmentStatePagerAdapter(fm) {
    public int getCount() {
        return titles.size();
    }

    public Fragment getItem(int position) {
        MyFragment fragment = new MyFragment();
        fragment.setTitle(titles.get(position));
        return fragment;
    }

    public int getItemPosition(Object item) {
        MyFragment fragment = (MyFragment)item;
        String title = fragment.getTitle();
        int position = titles.indexOf(title);

        if (position >= 0) {
            return position;
        } else {
            return POSITION_NONE;
        }
    }
});

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

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

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


4
কাজ করে না, এটি এখনও কিছু আপডেট করে না ... আমার কোড পোস্ট করেছে।
আইএক্সএক্স

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

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

12
আপনি ঠিক বলেছেন, অ্যাডাপ্টারের ক্লাসটি ফ্র্যাগমেন্টস্টেটপেজারএডাপ্টারে পরিবর্তন করা আমার সমস্ত সমস্যার সমাধান করেছে। ধন্যবাদ!
আইএক্সএক্স

2
এমনকি আমি ব্যবহারের সময় POSITION_NONE ফিরে আসার পরেও আমি FragmentStatePagerAdapterদেখতে পাচ্ছি যে এটি আমার খণ্ডটি সরিয়ে দেয় এবং নতুন উদাহরণটি তৈরি করে। তবে নতুন উদাহরণটি একটি পুরানো টুকরাটির অবস্থার সাথে একটি সেভড ইনস্ট্যান্সস্টেট বান্ডিল গ্রহণ করে। আবার তৈরি করার সময় বান্ডিলটি শূন্য হয়ে যাওয়ার ফলে আমি খণ্ডটিকে কীভাবে সম্পূর্ণ ধ্বংস করব?

142

পুরো দৃশ্য বিনোদন POSITION_NONEথেকে ফিরে আসার পরিবর্তে getItemPosition()এটি করুন:

//call this method to update fragments in ViewPager dynamically
public void update(UpdateData xyzData) {
    this.updateData = xyzData;
    notifyDataSetChanged();
}

@Override
public int getItemPosition(Object object) {
    if (object instanceof UpdateableFragment) {
        ((UpdateableFragment) object).update(updateData);
    }
    //don't return POSITION_NONE, avoid fragment recreation. 
    return super.getItemPosition(object);
}

আপনার টুকরা UpdateableFragmentইন্টারফেস প্রয়োগ করা উচিত :

public class SomeFragment extends Fragment implements
    UpdateableFragment{

    @Override
    public void update(UpdateData xyzData) {
         // this method will be called for every fragment in viewpager
         // so check if update is for this fragment
         if(forMe(xyzData)) {
           // do whatever you want to update your UI
         }
    }
}

এবং ইন্টারফেস:

public interface UpdateableFragment {
   public void update(UpdateData xyzData);
}

আপনার ডেটা ক্লাস:

public class UpdateData {
    //whatever you want here
}

1
এর অর্থ কি আপনার মেইনএ্যাকটিভিটির ইন্টারফেসটি প্রয়োগ করা দরকার ??? এখানে আমাকে সাহায্য করুন দয়া করে। আমার বর্তমান বাস্তবায়নে, আমি আমার মেইনএকটিভিটি ক্লাসটি টুকরোগুলির মধ্যে যোগাযোগকারী হিসাবে ব্যবহার করছি, সুতরাং আমি এই সমাধান সম্পর্কে বিভ্রান্ত হয়ে পড়েছিলাম।
রাকিব রাজভান্ডারী

1
ঠিক আছে, আমি পুরা বাস্তবায়ন যেখানে আমি আপডেট করছি সাথে অন্য স্থানে উত্তর Fragmentপরিবর্তনশীল একটি চেহারা আছে: stackoverflow.com/questions/19891828/...
এম-WaJeEh

@ এম-ওয়াজেএইচ কিছু উদাহরণ দয়া করে !!! আমার কাছে শহরের তালিকা সহ একটি তালিকা রয়েছে এবং শহরটি নির্বাচন করার পরে এই শহর সম্পর্কে তথ্য সহ ভিউপ্যাজার (3 পৃষ্ঠা) খোলে about এটা ঠিক কাজ করে। তবে অন্য কোনও সিটি ভিউপ্যাজার নির্বাচন করার পরে কেবলমাত্র 3 d page on refreshes the 1-st page only after swiping pages? thw 2ডি পৃষ্ঠা সর্বদা ফাঁকা থাকে। ধন্যবাদ
সের্গ

4
আমার কাজের জীবনের গত 2.5 দিনের জন্য আমি যে সমস্ত স্টাফ দেখেছি সেগুলির মধ্যে .. এটিই আমার পক্ষে কাজ করেছে .. সমস্ত ধরণের অ্যারিগো, ধন্যবাদ, স্প্যাসিবা, সুক্রান .. এন।
অরকুন ওজেন

2
ড্রাগনসের জননী! এটি একটি কবজির মতো কাজ করে, একমাত্র সমাধানটি আমার পক্ষে কাজ করেছিল ... অনেক কিছু !!
সেবাস্তিয়ান গেরেরো

24

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

1- উপরে বর্ণিত হিসাবে আপনাকে অবশ্যই ফ্র্যাগমেন্টস্টেটপেজারএডাপ্টার ব্যবহার করতে হবে।

2- মূল কার্যকলাপে আমি অনারুমুকে ওভাররাইড করে নিম্নলিখিতগুলি করি the

if (!(mPagerAdapter == null)) {
    mPagerAdapter.notifyDataSetChanged();
}

3-i getItemPosition()এমপেইজারএডাপ্টারে ওভাররাইড করে আবার ফিরে আসি POSITION_NONE

@Override
public int getItemPosition(Object object) {
    return POSITION_NONE;
}

কবজ মত কাজ করে


1
একটি সিটিওশন বাদে কাজ করে। আপনি যখন ভিউপিজারে সর্বশেষ আইটেমটি মুছবেন। তারপরে এটি তালিকা থেকে সরাবে না।
ভ্লাদো পান্ডিয়াস

আমি গতিশীলভাবে ভিউপেজারে বর্তমান খণ্ডের বাম এবং ডান উভয় অংশে টুকরা যোগ করছি। এই এক কাজ! ধন্যবাদ।
h8পাঠক

15

আমি এই সমস্যার মুখোমুখি হয়েছি এবং শেষ পর্যন্ত আজই এটি সমাধান করেছি, তাই আমি যা শিখেছি তা লিখে রাখি এবং আমি আশা করি এটি অ্যান্ড্রয়েডের ক্ষেত্রে নতুন ViewPagerএবং আমার মতো আপডেট হওয়া কারও পক্ষে সহায়ক হবে। আমি FragmentStatePagerAdapterএপিআই স্তরের 17 টি ব্যবহার করছি এবং বর্তমানে মাত্র 2 টুকরা রয়েছে। আমি মনে করি কিছু অবশ্যই সঠিক নয়, দয়া করে আমাকে সংশোধন করুন, ধন্যবাদ। এখানে চিত্র বর্ণনা লিখুন

  1. সিরিয়ালযুক্ত ডেটা মেমরিতে লোড করতে হয়। এটি একটি CursorLoader/ AsyncTask/ ব্যবহার করে করা যেতে পারে Thread। এটি স্বয়ংক্রিয়ভাবে লোড হয়েছে কিনা তা আপনার কোডের উপর নির্ভর করে। আপনি যদি এটি ব্যবহার করে থাকেন তবে CursorLoaderএটি নিবন্ধভুক্ত ডেটা পর্যবেক্ষক থাকার কারণে এটি স্বয়ংক্রিয়ভাবে লোড।

  2. আপনি কল করার পরে viewpager.setAdapter(pageradapter), অ্যাডাপ্টারগুলি getCount()ক্রমাগত টুকরোগুলি তৈরি করতে বলা হয়। সুতরাং যদি ডেটা লোড হচ্ছে, getCount()0 ফিরে আসতে পারে, সুতরাং কোনও তথ্য প্রদর্শিত না হওয়ার জন্য আপনাকে ডামি টুকরো তৈরি করতে হবে না।

  3. ডেটা লোড হওয়ার পরে, অ্যাডাপ্টারটি স্বয়ংক্রিয়ভাবে টুকরোগুলি তৈরি করবে না যেহেতু getCount()এখনও 0 রয়েছে, তাই আমরা আসলে লোড হওয়া ডেটা নম্বরটি ফিরিয়ে আনতে সেট করতে পারি getCount(), তারপরে অ্যাডাপ্টারে ফোন করুন notifyDataSetChanged()ViewPagerমেমরিতে ডেটা দ্বারা টুকরো টুকরো টুকরো (প্রথম প্রথম 2 টুকরো) তৈরি করা শুরু করুন। notifyDataSetChanged()ফিরে আসার আগে এটি করা হয়ে গেছে । তারপরে আপনার ViewPagerসঠিক টুকরোগুলি রয়েছে।

  4. ডাটাবেস এবং মেমরির ডেটা যদি আপডেট হয় (এর মাধ্যমে লিখুন), বা কেবল মেমরিতে ডেটা আপডেট করা হয় (ফিরে লিখুন), বা ডাটাবেসে কেবল ডেটা আপডেট করা হয় is শেষ দুটি ক্ষেত্রে যদি ডেটাবেস থেকে মেমরিতে স্বয়ংক্রিয়ভাবে লোড না করা হয় (উপরে বর্ণিত হিসাবে) ViewPagerএবং পেজার অ্যাডাপ্টারের শুধু মেমরি ডাটা মোকাবেলা।

  5. সুতরাং যখন মেমরিতে ডেটা আপডেট করা হয়, তখন আমাদের কেবল অ্যাডাপ্টারের কল করতে হবে notifyDataSetChanged()। যেহেতু খণ্ডটি ইতিমধ্যে তৈরি করা হয়েছে, অ্যাডাপ্টারেরকে রিটার্নের onItemPosition()আগে ডাকা হবে notifyDataSetChanged()। কিছুই করার দরকার নেই getItemPosition()। তারপরে ডেটা আপডেট করা হয়।


আপনি ডেটা আপডেট করার পরে (মেমোরিয়ায়) কিছু করার দরকার নেই, কেবল কল করুন notifyDataSetChanged()কেবলমাত্র স্বয়ংক্রিয়ভাবে আপডেট হয়েছে, কারণ আমি যে খণ্ডটি ব্যবহার করেছি (চার্টভিউ সহ) তা নিজেই রিফ্রেশ হবে। যদি এটি না হয়, একটি স্ট্যাটিক খণ্ডের মতো, আমাকে কল করতে হবে onItemPositon()এবং তার জন্য POSITION_NONE দুঃখিত হবে
অস্কারথেকট

কারও কি ধারণা আছে যে এই চিত্রটি তৈরি করতে কোন সরঞ্জামটি ব্যবহার করা হয়েছিল?
জুইসি

12

আপনার কোড destroyDrawingCache()পরে ভিউপ্যাজার চেষ্টা করুন notifyDataSetChanged()


3
একই অবস্থা. দুর্দান্ত কাজ আপনাকে ধন্যবাদ। আমি Fragmentsআমার ভিউ পেজারে ব্যবহার করছি না বিশেষ করে একটি কঠিন সময় ছিল । তাই আপনাকে ধন্যবাদ!
শেঠ

11

হতাশা ঘণ্টা এই সমস্যা কাটিয়ে ওঠার জন্য সর্বোপরি সমাধান চেষ্টা এবং মত অন্যান্য অনুরূপ প্রশ্ন অনেক সমাধান চেষ্টা করার সময় পর এই , এই এবং এই যা সব আমার সাথে FAILED এই সমস্যা সমাধানের জন্য এবং করতে ViewPagerপুরাতন ধ্বংস করতে Fragmentএবং ভরাট pagerসঙ্গে নতুন Fragmentএস। সমস্যাটি আমি নিম্নলিখিত হিসাবে সমাধান করেছি:

1)ViewPager ক্লাসটি FragmentPagerAdapterনিম্নলিখিত হিসাবে প্রসারিত করুন :

 public class myPagerAdapter extends FragmentPagerAdapter {

2) একটি আইটেম তৈরী ViewPagerযে সংরক্ষণ titleএবং fragmentনিম্নলিখিত হিসাবে:

public class PagerItem {
private String mTitle;
private Fragment mFragment;


public PagerItem(String mTitle, Fragment mFragment) {
    this.mTitle = mTitle;
    this.mFragment = mFragment;
}
public String getTitle() {
    return mTitle;
}
public Fragment getFragment() {
    return mFragment;
}
public void setTitle(String mTitle) {
    this.mTitle = mTitle;
}

public void setFragment(Fragment mFragment) {
    this.mFragment = mFragment;
}

}

3)ViewPager আমার FragmentManagerউদাহরণটি এটি আমার classহিসাবে সংরক্ষণের জন্য কনস্ট্রাক্টরটিকে তৈরি করুন :

private FragmentManager mFragmentManager;
private ArrayList<PagerItem> mPagerItems;

public MyPagerAdapter(FragmentManager fragmentManager, ArrayList<PagerItem> pagerItems) {
    super(fragmentManager);
    mFragmentManager = fragmentManager;
    mPagerItems = pagerItems;
}

4) একটি পদ্ধতি তৈরি করুন পুনরায় সেট adapterসমস্ত পূর্ববর্তী মুছে ফেলার মাধ্যমে নতুন তথ্য সাথে ডেটা fragmentথেকে fragmentManagerনিজেই সরাসরি করতে adapterনতুন সেট করতে fragmentনিম্নলিখিত হিসাবে আবার নতুন তালিকা থেকে:

public void setPagerItems(ArrayList<PagerItem> pagerItems) {
    if (mPagerItems != null)
        for (int i = 0; i < mPagerItems.size(); i++) {
            mFragmentManager.beginTransaction().remove(mPagerItems.get(i).getFragment()).commit();
        }
    mPagerItems = pagerItems;
}

5) ধারক থেকে Activityবা Fragmentনতুন ডেটা দিয়ে অ্যাডাপ্টারটি পুনরায় আরম্ভ করবেন না। setPagerItemsনিম্নলিখিত হিসাবে নতুন তথ্য দিয়ে পদ্ধতির মাধ্যমে নতুন তথ্য সেট করুন :

ArrayList<PagerItem> pagerItems = new ArrayList<PagerItem>();
    pagerItems.add(new PagerItem("Fragment1", new MyFragment1()));
    pagerItems.add(new PagerItem("Fragment2", new MyFragment2()));

    mPagerAdapter.setPagerItems(pagerItems);
    mPagerAdapter.notifyDataSetChanged();

আমি আসা করি এটা সাহায্য করবে.


আপনি কি আমার ইস্যুতে আমাকে সহায়তা করতে পারবেন stackoverflow.com/questions/40149039/…
অ্যালবার্ট

আপনি কি দয়া করে এই ইস্যুতে আমাকে সহায়তা করতে পারেন stackoverflow.com/questions/41547995/…
ভাইপার

10

কোনও কারণে উত্তরের কোনওটিই আমার পক্ষে কাজ করেনি তাই আমার ফ্রেগমেন্টস্টেটপেজারএডাপ্টারে সুপার না বলেই আমাকে পুনরুদ্ধার পদ্ধতিটি ওভাররাইড করতে হয়েছিল। কোড:

private class MyAdapter extends FragmentStatePagerAdapter {

    // [Rest of implementation]

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {}

}

1
এই এসও উত্তরে অন্য সমস্ত কিছুর চেষ্টা করার পরে, এটিই আমার পক্ষে কাজ করেছে। আমি () এমন একটি ক্রিয়াকলাপ শেষ করছি যা ক্রিয়াকলাপে ফিরে আসে যা প্রশ্নে থাকা পেজারআডাপ্টারকে হোস্ট করে। আমি চাই যে এই ক্ষেত্রে আমার সমস্ত টুকরোগুলি পুনরায় তৈরি হোক কারণ আমি যে কার্যক্রমটি সবে শেষ করেছি সেগুলি টুকরো টানতে ব্যবহৃত অবস্থায় পরিবর্তিত হতে পারে।
জনিলম্বদা

ওএমজি .. এটি কাজ করে .. এটি কাজ করে..কোডস: ডি আমার ক্ষেত্রে আমার ভিউপেজার বর্তমান আইটেমটি অপসারণ করা দরকার। তবে উপরের সমস্ত পদ্ধতি / পদক্ষেপ চেষ্টা করেও বর্তমান খণ্ডটি আপডেট হচ্ছে না।
রাহুল খুরানা

3

আমার প্রয়োজন অনুসারে বিল ফিলিপসের দেওয়া সমাধানটি আমি সামান্য সংশোধন করেছি slightly

private class PagerAdapter extends FragmentStatePagerAdapter{
    Bundle oBundle;
    FragmentManager oFragmentManager;
    ArrayList<Fragment> oPooledFragments;

public PagerAdapter(FragmentManager fm) {
    super(fm);
    oFragmentManager=fm;

    }
@Override
public int getItemPosition(Object object) {

    Fragment oFragment=(Fragment)object;
    oPooledFragments=new ArrayList<>(oFragmentManager.getFragments());
    if(oPooledFragments.contains(oFragment))
        return POSITION_NONE;
    else
        return POSITION_UNCHANGED;
    } 
}

যাতে getItemPosition()আয় POSITION_NONEকেবলমাত্র সেই টুকরা যা বর্তমানে জন্য FragmentManagerযখন getItemPositionবলা হয়। (দ্রষ্টব্য যে এটি FragmentStatePagerএবং এর সাথে ViewPagerযুক্ত কোনও ক্রিয়াকলাপে নয় এমন একটি খণ্ডে রয়েছে)


2

আমারও একই সমস্যা ছিল তবে বিদ্যমান সমাধানগুলিতে (হার্ড কোডেড ট্যাগের নাম ইত্যাদি) বিশ্বাস করতে চাই না এবং আমি এম ওয়াজেইহ এর সমাধানের কাজটি আমার পক্ষে করতে পারিনি। এখানে আমার সমাধান:

আমি অ্যারেতে getItem এ তৈরি করা টুকরোগুলির রেফারেন্স রাখি। এটি ততক্ষণ কাজ করে যতক্ষণ না কনফিগারেশনের কারণে ক্রিয়াকলাপটি ধ্বংস হয় না বা মেমরির অভাবে বা যাই হোক না কেন (-> ক্রিয়াকলাপে ফিরে আসার পরে টুকরাগুলি 'getItem' না করে আবার ডেকে ফেলা হয় এবং এভাবে অ্যারে আপডেট না করেই শেষ পর্যায়ে ফিরে আসে )।

এই সমস্যাটি এড়াতে আমি ইনস্ট্যান্টিয়েট আইটেমটি (ভিউগ্রুপ, ইনট) প্রয়োগ করেছি এবং আমার অ্যারেটিকে এখানে আপডেট করেছি:

        @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Object o = super.instantiateItem(container, position);
        if(o instanceof FragmentX){
            myFragments[0] = (FragmentX)o;
        }else if(o instanceof FragmentY){
            myFragments[1] = (FragmentY)o;
        }else if(o instanceof FragmentZ){
            myFragments[2] = (FragmentZ)o;
        }
        return o;
    }

সুতরাং, একদিকে আমি আনন্দিত যে আমি এমন একটি সমাধান পেয়েছি যা আমার পক্ষে কাজ করে এবং এটি আপনার সাথে ভাগ করে নিতে চেয়েছিলাম, তবে আমি আরও জিজ্ঞাসা করতে চেয়েছিলাম যে অন্য কেউ একইরকম কিছু চেষ্টা করেছিল কিনা এবং আমার কারণ না করার কোনও কারণ আছে কিনা? এটা কি এমন করে? এখনও পর্যন্ত এটি আমার পক্ষে খুব ভাল কাজ করে ...


আমি সম্পন্ন কিছু সম্পর্কিত করেছি stackoverflow.com/a/23427215/954643 , যদিও আপনি সম্ভবত থেকে আইটেম মুছে ফেলা আবশ্যক myFragmentsমধ্যে public void destroyItem(ViewGroup container, int position, Object object)পাশাপাশি যাতে আপনি আপনার মামুলি fragement রেফারেন্স দখল করে না।
কিউস

1

আমি ইন ইভেন্ট ইভেন্ট লাইব্রেরি Fragmentকনটেন্ট আপডেট করতে ViewPager। যুক্তিটি সহজ, কীভাবে ইভেন্টবাসের নথির মতো । FragmentPagerAdapterউদাহরণস্বরূপ এটি নিয়ন্ত্রণ করার দরকার নেই । কোডটি এখানে:

1: ইভেন্টগুলি সংজ্ঞায়িত করুন

কোন বার্তাটি আপডেট করার প্রয়োজন তা নির্ধারণ করুন।

public class UpdateCountEvent {
    public final int count;

    public UpdateCountEvent(int count) {
        this.count = count;
    }
}

2.প্রিয় গ্রাহকগণ

খন্ডে কোডের নীচে লিখুন যা আপডেটের প্রয়োজন।

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);  
    super.onStop();
}

public void onEvent(UpdateCountEvent event) {//get update message
    Toast.makeText(getActivity(), event.count, Toast.LENGTH_SHORT).show();
}

3.পোস্ট ইভেন্ট

অন্যান্য Activityবা অন্যগুলিতে কোডের নীচে লিখুন Fragmentযার প্যারামিটারটি আপডেট করতে হবে

//input update message
EventBus.getDefault().post(new UpdateCountEvent(count));

1

আপনি যদি ফ্র্যাগমেন্টস্টেটপেজারএডাপ্টার ব্যবহার করতে চান তবে দয়া করে https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary% দেখুন 20 স্টার এবং গোষ্ঠীবিশেষ = & সাজানো = & আইডি = 37990 । ফ্রেগমেন্টস্টেটপেজার অ্যাডাপ্টারের সাথে সমস্যাগুলি রয়েছে যা আপনার ব্যবহারের ক্ষেত্রে সমস্যা হতে পারে বা নাও পারে।

এছাড়াও, লিঙ্কটির কয়েকটি সমাধানও রয়েছে..যদি আপনার প্রয়োজন অনুসারে উপযুক্ত হতে পারে।


এই URL টি থেকে আমি সমাধান খুঁজে পেয়েছি। আমি এই কোডটি জিস্ট. github.com/ypresto/8c13cb88a0973d071a64 থেকে সংশোধিত ফ্রেগমেন্টস্টেট পেজারএডাপ্টারটি আমার কোডটিতে ব্যবহার করেছি এবং এটি যেমনটি অনুমান করা হয়েছে তেমন কাজ শুরু করে।
রাফায়েল

কুল। হ্যাঁ. লিঙ্কের কয়েকটি সমাধানও রয়েছে।
সিজিআর

1

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

myVPager.setAdapter(null);
myFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager(),newList);
myVPager.setAdapter(myFragmentAdapter);

আপনার অ্যাডাপ্টারের অবশ্যই ফ্রেগমেন্টস্টেটপেজারএডাপ্টার প্রসারিত হতে হবে তা নিশ্চিত হন


1

এখানে আমার বাস্তবায়ন যা @ বিল ফিলিপস ওয়ান থেকে তথ্য অন্তর্ভুক্ত করে ডেটা পরিবর্তিত হয়ে যাওয়া ব্যতীত বেশিরভাগ সময় টুকরো টুকরো হয়ে যায়। সহজ, এবং ভাল কাজ করে বলে মনে হচ্ছে।

MyFragmentStatePagerAdapter.java

private boolean mIsUpdating = false;
public void setIsUpdating(boolean mIsUpdating) {
        this.mIsUpdating = mIsUpdating;
    }


@Override
public int getItemPosition(@NonNull Object object) {

    if (mIsUpdating) {
        return POSITION_NONE;
    }
    else {
        return super.getItemPosition(object);
    }
}

MyActivity.java

mAdapter.setIsUpdating(true);
mAdapter.notifyDataSetChanged();
mAdapter.setIsUpdating(false);

0

আমি অনেকগুলি ভিন্ন পদ্ধতির চেষ্টা করছিলাম, সত্যিই কেউই আমার সমস্যা বুনেনি। আপনার সকলের সরবরাহিত সমাধানের মিশ্রণ দিয়ে আমি কীভাবে এটি সমাধান করব তা নীচে দেওয়া হল। ধন্যবাদ সবাইকে.

class PagerAdapter extends FragmentPagerAdapter {

    public boolean flag_refresh=false;

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

    @Override
    public Fragment getItem(int page) {
        FragmentsMain f;
        f=new FragmentsMain();
        f.page=page;
        return f;
    }

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

    @Override
    public int getItemPosition(Object item) {
        int page= ((FragmentsMain)item).page;

        if (page == 0 && flag_refresh) {
            flag_refresh=false;
            return POSITION_NONE;
        } else {
            return super.getItemPosition(item);
        }
    }

    @Override
    public void destroyItem(View container, int position, Object object) {

        ((ViewPager) container).removeView((View) object);
    }
}

আমি অনারিউম () এর পরে কেবল পৃষ্ঠা 0 রিফ্রেশ করতে চাই।

 adapter=new PagerAdapter(getSupportFragmentManager());
 pager.setAdapter(adapter);

@Override
protected void onResume() {
    super.onResume();

    if (adapter!=null) {
        adapter.flag_refresh=true;
        adapter.notifyDataSetChanged();
    }
}

আমার টুকরো মেইনে, সর্বজনীন পূর্ণসংখ্যার "পৃষ্ঠা" রয়েছে, এটি আমাকে পৃষ্ঠাটি রিফ্রেশ করতে চাই কিনা তা আমাকে জানাতে পারে।

public class FragmentsMain extends Fragment {

private Cursor cursor;
private static Context context;
public int page=-1;

0

আমি জানি পার্টির জন্য দেরি হয়ে গেছে। আমি TabLayout#setupWithViewPager(myViewPager);ঠিক পরে ফোন করে সমস্যার সমাধান করেছিFragmentPagerAdapter#notifyDataSetChanged();


0

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

এই সীমাবদ্ধতার সাথে, এই সমাধানটি নিরাপদ এবং উত্পাদনে ব্যবহারের জন্য নিরাপদ হওয়া উচিত।

private void updateFragment(Item item) {

    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    for (Fragment fragment : fragments) {

        if (fragment instanceof MyItemFragment && fragment.isVisible()) {
            ((MyItemFragment) fragment).update(item);
        }

    }
}

যদি আপনার একই খণ্ডের একাধিক সংস্করণ থাকে তবে আপনি সেই একই কৌশলটি ব্যবহার করতে পারেন সেই খণ্ডগুলিতে পদ্ধতিগুলি কল করতে এটি নির্ধারণ করতে যে এটি আপডেট করতে চান সেই খণ্ডটি is


0

এটি কারওর পক্ষে সহায়ক হতে পারে - আমার ক্ষেত্রে কোনও নতুন পৃষ্ঠা সন্নিবেশ করানোর সময় ভিউ পেজার দুবার বিদ্যমান খণ্ডের অবস্থানের জন্য জিজ্ঞাসা করছিল, কিন্তু নতুন আচরণের জন্য জিজ্ঞাসা করছে না, কারণ ভুল আচরণ এবং ডেটা প্রদর্শন করছে না।

  1. ফ্রেগমেন্টস্টেটপেজারএডাপ্টারের জন্য উত্সটি অনুলিপি করুন (মনে হয় যুগে যুগে আপডেট হয়নি)।

  2. ওভাররাইড বিজ্ঞপ্তি ডেটাসেট চেঞ্জড ()

    @Override
    public void notifyDataSetChanged() {
        mFragments.clear();
        super.notifyDataSetChanged();
    }
  3. ক্র্যাশগুলি রোধ করার জন্য আইটেম () নষ্ট আইটেমটিতে একটি স্যানিটি চেক যুক্ত করুন:

    if (position < mFragments.size()) {
        mFragments.set(position, null);
    }

0

আমি উপরের সমস্ত উত্তর এবং অন্যান্য বেশ কয়েকটি পোস্ট দিয়ে গিয়েছি তবে এখনও আমার পক্ষে কাজ করা কিছু খুঁজে পেল না (বিভিন্ন টুকরো টাইপের পাশাপাশি ট্যাবগুলিকে গতিশীলভাবে যুক্ত এবং মুছে ফেলা)। FWIW নিম্নলিখিত পন্থাটি আমার পক্ষে কাজ করেছে (অন্য কারও ক্ষেত্রে যদি সমস্যা থাকে)।

public class MyFragmentStatePageAdapter extends FragmentStatePagerAdapter {
    private static final String TAB1_TITLE = "Tab 1";
    private static final String TAB2_TITLE = "Tab 2";
    private static final String TAB3_TITLE = "Tab 3";

    private ArrayList<String> titles = new ArrayList<>();
    private Map<Fragment, Integer> fragmentPositions = new HashMap<>();


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


    public void update(boolean showTab1, boolean showTab2, boolean showTab3) {
        titles.clear();

        if (showTab1) {
            titles.add(TAB1_TITLE);
        }
        if (showTab2) {
            titles.add(TAB2_TITLE);
        }
        if (showTab3) {
            titles.add(TAB3_TITLE);
        }
        notifyDataSetChanged();
    }


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

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = null;

        String tabName = titles.get(position);
        if (tabName.equals(TAB1_TITLE)) { 
            fragment =  Tab1Fragment.newInstance();
        } else if (tabName.equals(TAB2_TITLE)) {
            fragment =  Tab2Fragment.newInstance();
        } else if (tabName.equals(TAB3_TITLE)) {
            fragment =  Tab3Fragmen.newInstance();
        } 

        ((BaseFragment)fragment).setTitle(tabName);
        fragmentPositions.put(fragment, position);
        return fragment;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }

    @Override
    public int getItemPosition(Object item) {
        BaseFragment fragment = (BaseFragment)item;
        String title = fragment.getTitle();
        int position = titles.indexOf(title);

        Integer fragmentPosition = fragmentPositions.get(item);
        if (fragmentPosition != null && position == fragmentPosition) {
            return POSITION_UNCHANGED;
        } else {
            return POSITION_NONE;
        }
    }

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

0

সূচির ভিত্তিতে টুকরো পুনরায় তৈরি করতে বা পুনরায় লোড করতে চাইলে ফ্রেগমেন্টপেজারএডাপ্টারের পরিবর্তে ফ্র্যাগমেন্টস্টেটপেজারএডাপ্টার ব্যবহার করুন উদাহরণস্বরূপ আপনি যদি ফার্স্টফ্র্যাগমেন্ট ব্যতীত অন্য খণ্ডকে পুনরায় লোড করতে চান তবে আপনি উদাহরণটি যাচাই করতে পারেন এবং এটির মতো ফিরে আসুন

 public int getItemPosition(Object item) {
    if(item instanceof FirstFragment){
       return 0;
    }
    return POSITION_NONE;
 }

0

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

    if (mFragments.size() > position) {
        Fragment f = mFragments.get(position);

        if (f != null) {
            int newPosition = getItemPosition(f);
            if (newPosition == POSITION_UNCHANGED) {
                return f;
            } else if (newPosition == POSITION_NONE) {
                mFragments.set(position, null);
            } else {
                mFragments.set(newPosition, f);
            }
        }
    }

ভিত্তিক অ্যান্ড্রয়েডএক্স ফ্রেগমেন্টস্টেটপেইজারএডাপ্টার.জভা, কারণ mFragmentsnotifDataSetChanged () কল করার সময় এর উপাদানগুলির অবস্থান পরিবর্তন হয় না।

সূত্র: https://github.com/cuichanghao/infivt/blob/master/library/src/main/java/cc/cuichanghao/library/FragmentStatePagerChangeableAdapter.java

উদাহরণ: https://github.com/cuichanghao/infivt/blob/master/app/src/main/java/cc/cuichanghao/infivt/MainActivityChangeablePager.kt

কীভাবে কাজ করবেন তা নিশ্চিত করতে আপনি এই প্রকল্পটি চালাতে পারেন। https://github.com/cuichanghao/infivt

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