3

I have searched for various answers on StackOverflow but not able to find something near to this. I know how to refresh fragment but i dont know how to refresh fragment which is actualy in tab layout.I have an activity and i have implemented tablayout with viewpager. And i have recyclerview in one of the fragment of tablayout. And in that recycler view i have a button that reloads the page. But the problem is i reload the complete activity and i see the first tab.While the recyclerview fragment is in second tab. So how do i reload the fragment from the recyclerview and dont let complete activity refresh. If i refresh complete activity then again first layout will be visible on front screen and user wil have to swipe to second tab again, which is not preferable. Heres my code of recylerview adapter of fragment of second tab:

    public class Recieved_Reviews_adapter extends RecyclerView.Adapter<Recieved_Reviews_adapter.ViewHolder>
{

Context context;
ArrayList<reviews_model> arraylist_reviews_models;



        public Recieved_Reviews_adapter(Context context, ArrayList<reviews_model> reviews_models) {
            this.context=context;
            this.arraylist_reviews_models = reviews_models;




        }

        @Override
        public Recieved_Reviews_adapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
            View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cardview__recieved_reviews, viewGroup, false);
            return new ViewHolder(view);


        }

        @Override
        public void onBindViewHolder(final Recieved_Reviews_adapter.ViewHolder viewHolder, int i) {


            viewHolder.imageView.setImageResource(arraylist_reviews_models.get(i).getReview_images());
            viewHolder.reviewers_name.setText(" "+ arraylist_reviews_models.get(i).getReviewer_name());
            viewHolder.reviews.setText("\" "+ arraylist_reviews_models.get(i).getReviews()+"\"");
            viewHolder.reviews_ratingbar.setRating(arraylist_reviews_models.get(i).getReviews_rating());

    viewHolder.img_btn_reply.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            viewHolder.img_btn_reply.setVisibility(View.GONE);
            EditText et_reply= new EditText(context);
            et_reply.setHint("Reply");
            Button btn_sumbit= new Button(context);
            btn_sumbit.setText("Submit");
            btn_sumbit.setGravity(Gravity.CENTER);
            btn_sumbit.setBackgroundColor(context.getResources().getColor(R.color.colorPrimary));
          btn_sumbit.setTextColor(context.getResources().getColor(R.color.TextColorWhite));
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(120, 40);
            params.setMargins(20, 20, 20, 20);
            params.gravity=Gravity.CENTER;
            btn_sumbit.setLayoutParams(params);

          et_reply.setGravity(Gravity.CENTER);
            viewHolder.linearLayout_received_reviews.addView(et_reply,viewHolder.linearLayout_received_reviews.getChildCount());
            viewHolder.linearLayout_received_reviews.addView(btn_sumbit);

            btn_sumbit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {


                           //Refreshing base activity rather 
                            ((Reviews)context).finish();
                            context.startActivity(((Reviews)context).getIntent());

                        });
        }

        @Override
        public int getItemCount() {
            return arraylist_reviews_models.size();

        }



        public class ViewHolder extends RecyclerView.ViewHolder {
    CircleImageView imageView;
    RatingBar reviews_ratingbar;
    TextView reviewers_name;
    TextView reviews;
    LinearLayout linearLayout_received_reviews;
    ImageButton img_btn_reply;
    Button submit;
            public ViewHolder(View view) {
                super(view);
                imageView=(CircleImageView) view.findViewById(R.id.img_review);
                imageView.setBorderColor(context.getResources().getColor(R.color.darkgrey));
                reviews_ratingbar=(RatingBar)view.findViewById(R.id.ratingbar_reviews);
                reviewers_name=(TextView)view.findViewById(R.id.tv_reviewer_name);
                reviews=(TextView) view.findViewById(R.id.tv_the_reviews);
    img_btn_reply =(ImageButton)view.findViewById(R.id.img_btn_received_review_reply);
            linearLayout_received_reviews=(LinearLayout)view.findViewById(R.id.linear_layout_recieved_reviews);


            }

        }



    }

And heres my activity code:

public class Reviews extends AppCompatActivity {


    ViewPager simpleViewPager;
    TabLayout tabLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_reviews);

        init();
        listener();

    }



    private void init() {
        //this method initializes all the views

        simpleViewPager = (ViewPager) findViewById(R.id.simpleViewPager);
        tabLayout = (TabLayout) findViewById(R.id.simpleTabLayout);
        TabLayout.Tab firstTab = tabLayout.newTab();
        firstTab.setText("Given");
        TabLayout.Tab secondTab = tabLayout.newTab();
        secondTab.setText("Recieved");
        tabLayout.addTab(firstTab);
        tabLayout.addTab(secondTab);
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
        PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
        simpleViewPager.setAdapter(adapter);
        simpleViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));


    }











    private void listener() {
        //this method sets onclick on tab

        tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(simpleViewPager));

    }

And heres my pageradapter of viewpager/tablayout:

public class PagerAdapter extends FragmentStatePagerAdapter {
    int mNumOfTabs;

    public PagerAdapter(FragmentManager fm, int NumOfTabs) {
        super(fm);
        this.mNumOfTabs = NumOfTabs;
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                Given_reviews tab1 = new Given_reviews();
                return tab1;
            case 1:
                Received_reviews tab2 = new Received_reviews();
                return tab2;

            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        return mNumOfTabs;
    }
}public class PagerAdapter extends FragmentStatePagerAdapter {
    int mNumOfTabs;

    public PagerAdapter(FragmentManager fm, int NumOfTabs) {
        super(fm);
        this.mNumOfTabs = NumOfTabs;
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                Given_reviews tab1 = new Given_reviews();
                return tab1;
            case 1:
                Received_reviews tab2 = new Received_reviews();
                return tab2;

            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        return mNumOfTabs;
    }
}
kloss91
  • 33
  • 1
  • 8
  • Reloading fragment is not the solution . You have to call fragment to refresh its data . Have look at [This](https://stackoverflow.com/questions/20474695/communication-between-fragments-in-viewpager). – ADM Jan 08 '18 at 05:53
  • no not a duplicate ,see, i have to refresh my fragment based on button click which is inside card of recyclerview. – kloss91 Jan 08 '18 at 05:56
  • 1
    @adm Thx for the link mate, see basicaly what i am trying to do is make api call on button click then show the response in the same card. I dont know what to do. – kloss91 Jan 08 '18 at 06:02
  • Same card or on same fragment ? Your answer is already in that link . just follow one answer and you are good to go . – ADM Jan 08 '18 at 06:04
  • on the same card bro , its like reviews thing, every card is a question. And a user can reply to every question. So every question will have its reply in its own card. Just the refreshing thing is vexing me. – kloss91 Jan 08 '18 at 06:07
  • What's exactly you want to refresh the fragment? To apply your layout change(hide img_btn_reply button and add new btn_sumbit, et_reply)? If it's true it will not work when you reloading fragment. It is due to the onBindViewHolder will call again and your layout come to previous state before click img_btn_reply. The logic of layout binding should depend on data. Any action like click button should change data or at least temporary variable. Then call notifyItemChanged/notifyDataSetChanged will work and update/refresh your recyclerView. – Truong Giang Dam Jan 08 '18 at 07:08

2 Answers2

1

Dont take this as an answer but rather a suggestive comment to your question (since i cant comment yet ). If i understood correctly you want to refresh your layout when button is clicked, why not use a swipe refresh layout and override the onRefresh method, in this method you can perform your API call and notifyDataSetChanged().

Ahmad Sabeh
  • 526
  • 5
  • 18
  • But in this i cant implement particular card's button's onclick.For example, you dont swipe ur page in facebook when you reply to a comment, you just hit the reply button. – kloss91 Jan 08 '18 at 14:26
0

In your case, all you need to do is make an API call in response to the button click on the Recyclerview item. Update it when you receive a response from your server, and call adapter.notifyItemChanged(itemPositionInAdapter).

You DO NOT need to recreate the activity/fragment.

Puneet
  • 653
  • 1
  • 7
  • 18
  • but i am making api call from the button on the card itself, how i am supposed to call notifyItemChanged(itemPositionInAdapter) in the onbindviewholder? – kloss91 Jan 08 '18 at 07:39
  • Handle the `onClick` event from your card buttons such that proxy it to your fragment with adapter position & any relevant info you need. Call your API, and then when you get back the API response update the `adapter` data set from your fragment, and call `notifyItemChanged`. – Puneet Jan 08 '18 at 09:29
  • that is all my question in the first place, how to do that proxy thing? – kloss91 Jan 08 '18 at 10:11
  • I am going to describe it how but coding is your job. (1) Create a new `Interface` with a single method (ex.onButtonClicked) that takes adapter position, Object backing the data as parameters (Button's onClick is also an interface). (2) Have your fragment implement the interface. (3) Pass an instance of your interface when creating your adapter, and store it in your adapter. (4) In your button's onClick handler, call the interface's onButtonClicked with the requisite parameters. (5) Now, your fragment can go ahead and call the API, receive response and update the RecyclerView. – Puneet Jan 08 '18 at 12:51
  • Definitely coding is my job, i am just asking for guidance. Because my adapter is getting larger, and i thought same to use something like interface like we do in callbacks. I will try to implement what you said , thanks for your efforts mate. – kloss91 Jan 08 '18 at 14:59