Analysis of viewpager + fragment data update Problems

Source: Internet
Author: User
In an Android app, we can use the fragmentpageadapter to process the horizontal sliding of multiple fragment pages. However, when the dataset corresponding to fragment changes, we all want to call madapter. notifydatasetchanged () is used to trigger the fragment page to adjust or regenerate its content. However, when we use yydatasetchanged (), we will find that this method does not take effect. So why is that? I have encountered the same problem and cannot solve it all the time. The messy answers I have provided on the Internet are not the correct solutions. I finally completely solved this problem this morning. Let's take a look at the source code of fragmentpageradapter.
    @Override      public Object instantiateItem(ViewGroup container, int position) {          if (mCurTransaction == null) {              mCurTransaction = mFragmentManager.beginTransaction();          }                final long itemId = getItemId(position);                // Do we already have this fragment?          String name = makeFragmentName(container.getId(), itemId);          Fragment fragment = mFragmentManager.findFragmentByTag(name);          if (fragment != null) {              if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);              mCurTransaction.attach(fragment);          } else {              fragment = getItem(position);              if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);              mCurTransaction.add(container.getId(), fragment,                      makeFragmentName(container.getId(), itemId));          }          if (fragment != mCurrentPrimaryItem) {              fragment.setMenuVisibility(false);              fragment.setUserVisibleHint(false);          }                return fragment;      }  

We pay special attention to the following sentence:
    String name = makeFragmentName(container.getId(), itemId);      Fragment fragment = mFragmentManager.findFragmentByTag(name);  

Based on the original code, we can know that the system adds a label to each fragment and uses the label to find the corresponding fragment. So when we enter fragment for the second time, the fragment oncreate, the oncreateview method will not be called, because the getitem () method in fragmentpageadapter will not be called at all, because the system will find the corresponding fragment based on the tag. if it already exists, it will not be called, fragment has a caching mechanism here. So if we must update the fragment, Then how should we deal with it? We can also treat people with their own ways, we can find the corresponding fragment through the tag to update the fragment. Let's start now.

Let's first define a list <string> taglist to store the tag.

private List<String> tagList;
The second part overrides the instantiateitem method and stores the label corresponding to fragment in the taglist set.
    public Object instantiateItem(ViewGroup container, int position) {          tagList.add(makeFragmentName(container.getId(), getItemId(position)));          return super.instantiateItem(container, position);      }  
Makefragmentname () is the method for labeling fragment in the source code of fragmentpageadapter.
public static String makeFragmentName(int viewId, int index) {return "android:switcher:" + viewId + ":" + index;}

Step 3: Write an update () method in the adapter.

public void update(int item) {Fragment fragment = fm.findFragmentByTag(tagList.get(item));if (fragment != null) {switch (item) {case 0:break;case 1:((QueryFragment) fragment).update();break;case 2:break;default:break;}}}

We can find that there is also an update () method in queryfragment. This method is the method to be used to update the corresponding fragment using the interface return mechanism, the content in the method can be compiled according to your own needs.

Now, everything is ready to implement the data update problem of fragment, which can be achieved through the interface return mechanism.


First, we define an interface to implement the main activity.

 

    public interface FragmentListener {                public void onFragmentClickListener(int item);      }  

For example, if we have inserted data in a fragment and we need bfragment to display the data, then we are now in the onattach method of afragment.
    public void onAttach(Activity activity) {          super.onAttach(activity);          try {              listener = (FragmentListener)activity;          } catch (Exception e) {              e.printStackTrace();                     }      }  
Then we call this interface in afragment when updating data.
if (listener != null) {listener.onFragmentClickListener(1);}

Then we return to the activity to implement the method in this interface and update the bfragment interface.
public void onFragmentClickListener(int item) {adapter.update(item);adapter.update(item);}

I'm done. paste the complete mainacitivity code!
package com.example.account.main;import java.util.ArrayList;import java.util.List;import com.example.account.add.AddFragment;import com.example.account.query.QueryFragment;import com.example.account.setting.SettingFragment;import com.example.account.utils.PagerSlidingTabStrip;import com.melhc.xiji.R;import android.annotation.SuppressLint;import android.content.Intent;import android.graphics.Color;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.ViewPager;import android.util.DisplayMetrics;import android.util.TypedValue;import android.view.KeyEvent;import android.view.ViewGroup;import android.widget.Toast;public class MainActivity extends FragmentActivity implements FragmentListener{private MyPagerAdapter adapter;private AddFragment addFragment;private List<String> tagList;private SettingFragment settingFragment;private boolean isExit;private QueryFragment queryFragment;private ViewPager pager;private PagerSlidingTabStrip tabs;private FragmentManager fm;private DisplayMetrics dm;private List<Fragment> list;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);pager = (ViewPager) findViewById(R.id.pager);tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);initFragment();fm = getSupportFragmentManager();tagList = new ArrayList<String>();adapter = new MyPagerAdapter(fm);pager.setAdapter(adapter);tabs.setViewPager(pager);}public void initFragment() {list = new ArrayList<Fragment>();addFragment = new AddFragment();queryFragment = new QueryFragment();settingFragment = new SettingFragment();list.add(addFragment);list.add(queryFragment);list.add(settingFragment);}public class MyPagerAdapter extends FragmentPagerAdapter {public MyPagerAdapter(FragmentManager fm) {super(fm);}private final String[] titles = { "1", "2", "3" };@Overridepublic CharSequence getPageTitle(int position) {return titles[position];}@Overridepublic int getCount() {return titles.length;}@Overridepublic Fragment getItem(int position) {return list.get(position);}public Object instantiateItem(ViewGroup container, int position) {tagList.add(makeFragmentName(container.getId(),(int) getItemId(position)));return super.instantiateItem(container, position);}public void update(int item) {Fragment fragment = fm.findFragmentByTag(tagList.get(item));if (fragment != null) {switch (item) {case 0:break;case 1:((QueryFragment) fragment).update();break;case 2:break;default:break;}}}}public static String makeFragmentName(int viewId, int index) {return "android:switcher:" + viewId + ":" + index;}public void onFragmentClickListener(int item) {adapter.update(item);adapter.update(item);}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.