4

I have a MainActivity and a HomeTabs with three tabs(A B C) all of them are Fragment. I set a onRefresh on tab C. When I trigger onRefresh that its view is gone. Why is that? I couldn't solve it.

Any help would be appreciated. Thanks in advance.

Here's my HomeTabs:

public class HomeTabs extends Fragment {
    private Context context;
    private TabLayout tabLayout;

    private int[] imageResId = {R.drawable.input_icon_color,
            R.drawable.note_icon_color,
            R.drawable.analytics_icon_color};

    public HomeTabs() {
        // Required empty public constructor
    }

    public static HomeTabs newInstance() {
        return new HomeTabs();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home_tabs, container, false);

        tabLayout = (TabLayout) view.findViewById(R.id.tabLayout);
        tabLayout.addTab(tabLayout.newTab().setText(getResources().getString(R.string.tab1)));
        tabLayout.addTab(tabLayout.newTab().setText(getResources().getString(R.string.tab2)));
        tabLayout.addTab(tabLayout.newTab().setText(getResources().getString(R.string.tab3)));
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        final ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewPagerDataReport);

        ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter(viewPagerAdapter);

        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

        tabLayout.getTabAt(0).setIcon(R.drawable.input_icon);
        tabLayout.getTabAt(1).setIcon(imageResId[1]);
        tabLayout.getTabAt(2).setIcon(imageResId[2]);

        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());/

                int id = tab.getPosition();
                if (id == 0) {
                    tabLayout.getTabAt(0).setIcon(R.drawable.input_icon);
                    tabLayout.getTabAt(1).setIcon(imageResId[1]);
                    tabLayout.getTabAt(2).setIcon(imageResId[2]);
                }

                if (id == 1) {
                    tabLayout.getTabAt(0).setIcon(imageResId[0]);
                    tabLayout.getTabAt(1).setIcon(R.drawable.note_icon);
                    tabLayout.getTabAt(2).setIcon(imageResId[2]);
                }

                if (id == 2) {
                    tabLayout.getTabAt(0).setIcon(imageResId[0]);
                    tabLayout.getTabAt(1).setIcon(imageResId[1]);
                    tabLayout.getTabAt(2).setIcon(R.drawable.analytics_icon);
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
            }
        });

        // My tab C position is 2 , when i refresh that i want to show tab C
        if (getActivity().getIntent().hasExtra("refresh")){
            tabLayout.getTabAt(2).select();
        }

        return view;
    }
}

Here is my tab C Fragment about refresh:

@Override
public void onRefresh() {
    refreshLayout.setRefreshing(false);

    MainActivity mainActivity = (MainActivity) getActivity();
    mainActivity.refreshFragment();
}

And the MainActivity:

public class MainActivity extends AppCompatActivity {

    private FrameLayout frameLayout;
    private Toolbar toolBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        toolBar = (Toolbar) findViewById(R.id.toolBar);
        setSupportActionBar(toolBar);
        getSupportActionBar().setTitle("");
        toolBar.setTitle(R.string.myAppName);
        toolBar.setNavigationIcon(R.drawable.medical_history32);
        toolBar.setTitleTextColor(Color.WHITE);

        frameLayout = (FrameLayout) findViewById(R.id.frameLayout);

        if (savedInstanceState == null) {
            switchFragment(HomeTabs.newInstance());
        }


    }

    public void switchFragment(Fragment fragment) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.replace(R.id.frameLayout, fragment);
        transaction.addToBackStack(null);
        transaction.commit();
    }



    public void setTitle(String title) {
        getSupportActionBar().setTitle(title);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            new DialogHandler(this).quickDialog(
                    getResources().getString(R.string.quick),
                    getResources().getString(R.string.confirm),
                    getResources().getString(R.string.cancel),
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                            finish();
                        }
                    }, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    });
        }
        return super.onKeyDown(keyCode, event);
    }


    public void refreshFragment() {
        //switchFragment(HomeTabs.newInstance());
        Intent intent = new Intent(this,MainActivity.class);
        intent.putExtra("refresh",true);
        startActivity(intent);
    }

}

Here's my tab C:

public class MyLineChart extends Fragment implements SwipeRefreshLayout.OnRefreshListener{
    private View view;
@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_my_line_chart, container, false);

        //................set my data

        return view;
    }

    @Override
    public void onRefresh() {
        refreshLayout.setRefreshing(false);

    }
Morton
  • 5,380
  • 18
  • 63
  • 118
  • 1
    Possible duplicate of: https://stackoverflow.com/questions/20702333/refresh-fragment-at-reload – Mustansir Jun 28 '17 at 07:49
  • Thanks for sharing the link , i have try it , it look like can be refreshed , but my tab C view is still gone when i refresh it. – Morton Jun 28 '17 at 07:59
  • What are you trying to achieve ? what your code is trying to do is - start the `HomeTabs` fragment, load the `ViewPager` inside the `HomeTabs` fragment. Then inside C tab's `onRefresh()`, your code is trying to replace the current `HomeTabs` fragment with a new instance of `HomeTabs` fragments. You sure thats what you want ? – zeekhuge Jun 28 '17 at 07:59
  • My structure is trigger `onRefresh` on tab C that will send the data to `HomeTabs` , when i reload HomeTabs it will show tab C not tab A. – Morton Jun 28 '17 at 08:04
  • Restarting the activity each time to refresh data is a really bad idea. Why can you just refresh your view in Tab C ? I am guessing thats where you want to show dynamic data/progress. Try setting the new data and then to refresh the view use `.invalidate()` – zeekhuge Jun 28 '17 at 08:13
  • You could also try to reload your `adaptor`: `adapter.notifyDataSetChanged();` – Mustansir Jun 28 '17 at 08:17
  • @ZeekHuge , your guess right , but how could i use .invalidate() ? – Morton Jun 28 '17 at 08:20
  • @Michal_196 . I had find some solution about `adapter.notifyDataSetChanger();` , but i do not know about how to trigger it if i set `onRefresh` on tab C in my case. – Morton Jun 28 '17 at 08:21
  • if its a simple view that you want to change, you can try this - https://stackoverflow.com/questions/41544799/listview-row-updation/41548246#41548246 – zeekhuge Jun 28 '17 at 08:26
  • @ZeekHuge I can't find my view id in tab C , so i just use `view.invalidate();`. It's not working what step i miss it ? – Morton Jun 28 '17 at 08:32
  • @徐博俊 probably you should edit the question to add code of tab C – zeekhuge Jun 28 '17 at 08:42
  • Sure , i have update my question that add tab C. – Morton Jun 28 '17 at 08:47
  • @徐博俊 now inside `onRefresh()`, call `view.invalidate()`. This `view` is the global variable in which you inflate the fragment layout and finally return in the `onCreateView()` – zeekhuge Jun 28 '17 at 11:50

3 Answers3

4

There are many ways to do it. If you are using ViewPager the best solution is found here.

You must implement (override) getItemPosition method in your page adapter to return (no position changed)

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

Then to update from anywhere, you just notify the adapter of a change

mPagerAdapter.notifyDataSetChanged();
Rami Alloush
  • 2,308
  • 2
  • 27
  • 33
2

Your below code for reload your fragment:

 FragmentTransaction ft = getFragmentManager().beginTransaction();                                   

 ft.detach(YourFragmentName.this).attach(YourFragmentName.this).commit();
Vishal Vaishnav
  • 3,346
  • 3
  • 26
  • 57
  • Thanks , it can be refresh , but my problem still there that tab C view is gone when i refresh. – Morton Jun 28 '17 at 08:10
1

first set tag to your fragment as "fragment"

 @Override
public void onRefresh() 
{
    Fragment currentFragment = getFragmentManager().findFragmentByTag("FRAGMENT");
    FragmentTransaction fragTransaction = getFragmentManager().beginTransaction();
    fragTransaction.detach(currentFragment);
    fragTransaction.attach(currentFragment);
    fragTransaction.commit();
}
Vishal Vaishnav
  • 3,346
  • 3
  • 26
  • 57