Not able to Update fragments text while swaping ca

2019-06-22 07:59发布

I am working on a card swipe and card flip functionality and I am using ViewPager and fragments.

My problem is I am not able to update TextView inside fragments as I swipe the card from left to right or right to left but when I flip the card it update the UI. I tried everything which is available over Internet but none of the soltuion is working for me.

I am following this link https://github.com/jamesmccann/android-view-pager-cards

Here is my code

public class CardContainerFragment extends Fragment {

private boolean cardFlipped = false;
static TextView textview;

public CardContainerFragment() {
    setHasOptionsMenu(true);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_card_container, container, false);
    LinearLayout ll = (LinearLayout)rootView.findViewById(R.id.layout);
    rootView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            flipCard();
        }
    });

    getChildFragmentManager()
            .beginTransaction()
            .add(R.id.container, new CardFrontFragment())
            .commit();

    Message msg = handler.obtainMessage();
    msg.arg1 = 1;
    handler.sendMessage(msg);

    return rootView;
}

final Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        int page = CardActivity.mViewPager.getCurrentItem();
        int page_index = page+1;
        String current_page = page_index + " of " + card_activity.deck_map.size();
        CardActivity.tv.setText(current_page);


       super.handleMessage(msg);
    }
};


public void flipCard() {
    Fragment newFragment = null;
    Message msg = handler.obtainMessage();
    msg.arg1 = 1;
    handler.sendMessage(msg);
    if (cardFlipped) {
        newFragment = new CardFrontFragment();
    } else {
        newFragment = new CardBackFragment();
    }

    getChildFragmentManager()
            .beginTransaction()
            .setCustomAnimations(
                    R.animator.card_flip_right_in, R.animator.card_flip_right_out,
                    R.animator.card_flip_left_in, R.animator.card_flip_left_out)
            .replace(R.id.container, newFragment)
            .commit();

    cardFlipped = !cardFlipped;
}

public static class CardFrontFragment extends Fragment {

    public CardFrontFragment() { }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_card, container, false);
        textview = (TextView)rootView.findViewById(R.id.card_front);
        String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
        Log.e("current Item",CardActivity.mViewPager.getCurrentItem()+"");
        String complete_text = card_front_string +" \n \n + \n Tap now to flip this card.";
        textview.setText(complete_text);
        return rootView;
    }
}

public static class CardBackFragment extends Fragment {

    public CardBackFragment() { }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_card_back, container, false);
        TextView textview = (TextView)rootView.findViewById(R.id.card_back);
        textview.setMovementMethod(new ScrollingMovementMethod());
        String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
        String deck_data = card_activity.deck_map.get(card_front_string);
        textview.setText(deck_data);
        return rootView;
    }
}

Here is my adapter code

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try {
        setContentView(R.layout.card_example);
        tv = (TextView)findViewById(R.id.tv_card_number);
        tv1 = (TextView)findViewById(R.id.tv_card_index);
        FragmentManager m = getFragmentManager();
        CardPagerAdapter adapter = new CardPagerAdapter(m);
        index = getIntent().getStringExtra("index");
        card_activity.cardCounter = Integer.parseInt(index);
        int count = card_activity.cardCounter;
        int final_count = count+1;
        String current_page = final_count+" of "+card_activity.deck_map.size();
        //CardActivity.tv.setText(current_page);
        mViewPager = (ViewPager) findViewById(R.id.view_pager);
       // mViewPager.setAllowedSwipeDirection(CustomViewPager.SwipeDirection.all);
        mViewPager.setAdapter(adapter);
        mViewPager.setCurrentItem(card_activity.cardCounter);
        //mViewPager.setOffscreenPageLimit(1);

        //mViewPager.setOnPageChangeListener(new pagechangelistener())


        //Log.e("current Item",CardActivity.mViewPager.getCurrentItem()+"");

    }catch(Exception e){
        e.printStackTrace();
    }
}

public class CardPagerAdapter extends android.support.v13.app.FragmentStatePagerAdapter {

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

    @Override
    public Fragment getItem(int i) {
        mViewPager.setOffscreenPageLimit(0);
        int page = mViewPager.getCurrentItem();
        int page_index = page+1;
        String current_page = " of " + card_activity.deck_map.size();
        tv.setText(current_page);
        tv1.setText(String.valueOf(page_index));
        CardContainerFragment cardContainerFragment = new CardContainerFragment();
        cardContainerFragment.current_index_front = page;
        cardContainerFragment.current_index_back = page;

        String card_front_string = card_activity.arraylst.get(page);
        CardContainerFragment.complete_text_front = card_front_string +" \n \n + \n Tap now to flip this card.";
        Bundle b = new Bundle();
        b.putInt("index",page);
        CardContainerFragment.complete_text_back = card_activity.deck_map.get(card_front_string);
        cardContainerFragment.setArguments(b);
        return cardContainerFragment;
    }

    @Override
    public int getCount() {
        int len = card_activity.deck_map.size();
        return len;
    }
    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

Please let me know what I am doing wrong here.

Thanks in advance

5条回答
劫难
2楼-- · 2019-06-22 08:26

You just have to set data to text view which is used in CardFrontFragment. Here when ever a swipe happens onCreateView() of CardContainerFragment is called. You are adding CardFrontFragment every time when onCreateView() is called. you need to use text view of CardFrontFragment instead of using textview of activity.

Just replace CardActivity.tv.setText(current_page);

with textView.setText(current_page);

Make sure the textview you have used in CardFrontFragment is available at class level.

you are using static fragments so textview must be static.

 private static TextView textView=null;

Hope this will work for you :)

查看更多
▲ chillily
3楼-- · 2019-06-22 08:30

As @david-rawson says

Don't use static fields CardActivity.mViewPager. See https://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity

Reason for this is that the ViewPager might/will create the views of your fragments before they are displayed to ensure you get that smooth animation that people love ViewPagers for. So the mViewPager calls a number of fragments createView() function at the same time, and at that time the mViewPager has an index for .getCurrentItem() which goes to the CardContainer on the page being viewed.

A better option would be for you to pass CardContainerFragment a String argument with the value for "completeText" which you want it to display whenever it creates either CardBackFragment or CardFrontFragment.

Go through this for more details.

查看更多
爷的心禁止访问
4楼-- · 2019-06-22 08:36

Have you tried this:

    tv.post(new Runnable() {
        @Override
        public void run() {
            CardActivity.tv.setText(current_page);
        }
    });
查看更多
欢心
5楼-- · 2019-06-22 08:37

I did something similar wihtin my App, and I manage the display of my TextView into the OnCreateView, with a switch case.

I tried to implent your code but did not have all your materials (like custom animator).

You should then try something like that:

public class CardContainerFragment extends AppCompatActivity {

private boolean cardFlipped = false;
static TextView textview;

/*public CardContainerFragment() {
    setHasOptionsMenu(true);
}*/

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.your_activity_name);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    /*
  The {@link ViewPager} that will host the section contents.
 */
    ViewPager mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        // This method will be invoked when a new page becomes selected.
        @Override
        flipCard();

        @Override
        public void onPageSelected(int position) {

        }

        // This method will be invoked when the current page is scrolled
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            // Code goes here
        }

        // Called when the scroll state changes:
        // SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
        @Override
        public void onPageScrollStateChanged(int state) {
            // Code goes here
        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_welcome, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {
    /**
     * The fragment argument representing the section number for this
     * fragment.
     */
    private static final String ARG_SECTION_NUMBER = "section_number";

    public PlaceholderFragment() {
    }

    /**
     * Returns a new instance of this fragment for the given section
     * number.
     */
    public static PlaceholderFragment newInstance(int sectionNumber) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        //Initializing data
        Context context = getContext();

        View rootView = inflater.inflate(R.layout.fragment_card, container, false);
        TextView textView = (TextView) rootView.findViewById(R.id.txtView);

        int fragment = getArguments().getInt(ARG_SECTION_NUMBER);

        switch (fragment)
        {
            case 1: //front card

                String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
                Log.e("current Item",CardActivity.mViewPager.getCurrentItem()+"");
                String complete_text = card_front_string +" \n \n + \n Tap now to flip this card.";
                textview.setText(complete_text);

                getChildFragmentManager()
                        .beginTransaction()
                        .add(R.id.container, new CardFrontFragment())
                        .commit();

                Message msg = handler.obtainMessage();
                msg.arg1 = 1;
                handler.sendMessage(msg);

                return rootView;

            case 2: //back card

                TextView textview = (TextView)rootView.findViewById(R.id.card_back);
                textview.setMovementMethod(new ScrollingMovementMethod());
                String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
                String deck_data = card_activity.deck_map.get(card_front_string);
                textview.setText(deck_data);

                getChildFragmentManager()
                        .beginTransaction()
                        .add(R.id.container, new CardFrontFragment())
                        .commit();

                Message msg = handler.obtainMessage();
                msg.arg1 = 1;
                handler.sendMessage(msg);

                return rootView;

            default:

                return rootView;

        }
    }
}


final Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        int page = CardActivity.mViewPager.getCurrentItem();
        int page_index = page+1;
        String current_page = page_index + " of " + card_activity.deck_map.size();
        CardActivity.tv.setText(current_page);


       super.handleMessage(msg);
    }
};


public void flipCard() {
    Message msg = handler.obtainMessage();
    msg.arg1 = 1;
    handler.sendMessage(msg);

    getChildFragmentManager()
            .beginTransaction()
            .setCustomAnimations(
                    R.animator.card_flip_right_in, R.animator.card_flip_right_out,
                    R.animator.card_flip_left_in, R.animator.card_flip_left_out)
            .replace(R.id.container, newFragment)
            .commit();
}

/**
 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
 * one of the sections/tabs/pages.
 */
public class SectionsPagerAdapter extends FragmentPagerAdapter {

    SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        return PlaceholderFragment.newInstance(position + 1);
    }

    @Override
    public int getCount() {
        // Show 2 total pages.
        return 2;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "SECTION 1";
            case 1:
                return "SECTION 2";
        }
        return null;
    }
}

The textView is displayed on your page, and when selecting the change, the content of your textview will be changed.

查看更多
兄弟一词,经得起流年.
6楼-- · 2019-06-22 08:40

Finally I am able to do this with some efforts.

After searching, I get to know that getItems (The method in CardPagerAdapter) is called two times because Android creates one extra fragments for smooth transition and I was sending or getting wrong position of fragments from getItems.

By letting the android to create one extra fragment and by sending correct position I am able to solve this issue.

Here is my updated code

public class CardActivity extends android.support.v4.app.FragmentActivity {

public TextView tv;
public static String index=null;
public static ViewPager mViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try {
        setContentView(R.layout.card_example);
        tv = (TextView)findViewById(R.id.tv_card_number);
        FragmentManager m = getFragmentManager();
        CardPagerAdapter adapter = new CardPagerAdapter(m);
        index = getIntent().getStringExtra("index");
        card_activity.cardCounter = Integer.parseInt(index);
        int count = card_activity.cardCounter;
        int final_count = count+1;
        String current_page = final_count+" of "+card_activity.deck_map.size();
        mViewPager = (ViewPager) findViewById(R.id.view_pager);
        mViewPager.setOffscreenPageLimit(0);
        mViewPager.setAdapter(adapter);
        mViewPager.setCurrentItem(card_activity.cardCounter);
        String current_page_temp =final_count+" of " + card_activity.deck_map.size();
        tv.setText(current_page_temp);

        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                Log.e("aaa",position+"");
                    String current_page = position+1 + " of " + card_activity.deck_map.size();
                    tv.setText(current_page);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }catch(Exception e){
        e.printStackTrace();
    }
}

    public class CardPagerAdapter extends android.support.v13.app.FragmentStatePagerAdapter {

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

    @Override
    public Fragment getItem(int i) {

        CardContainerFragment cardContainerFragment = new CardContainerFragment();
        Bundle b = new Bundle();
        b.putInt("index",i);
        cardContainerFragment.setArguments(b);
        return cardContainerFragment;
    }

    @Override
    public int getCount() {
        int len = card_activity.deck_map.size();
        return len;
    }
    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}
  }

==================================================================

public class CardContainerFragment extends Fragment {

private boolean cardFlipped = false;
int current_index=0;
static int pos = 0;
public CardContainerFragment() {
    /*setHasOptionsMenu(true);*/
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_card_container, container, false);
    LinearLayout ll = (LinearLayout)rootView.findViewById(R.id.layout);
    rootView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            flipCard();
        }
    });
    pos = getArguments().getInt("index");
    getChildFragmentManager()
            .beginTransaction()
            .add(R.id.container, new CardFrontFragment().newInstance(pos))
            .commit();
    card_activity.tempCounter = card_activity.tempCounter+1;
    return rootView;
}


public void flipCard() {
    Fragment newFragment = null;
    CardFrontFragment cardFrontFragment = null;
    CardBackFragment cardBackFragment = null;

    if (cardFlipped) {
        newFragment = CardFrontFragment.newInstance(CardActivity.mViewPager.getCurrentItem());
    } else {
        newFragment = cardBackFragment.newInstance(CardActivity.mViewPager.getCurrentItem());
    }

    getChildFragmentManager()
            .beginTransaction()
            .setCustomAnimations(
                    R.animator.card_flip_right_in, R.animator.card_flip_right_out,
                    R.animator.card_flip_left_in, R.animator.card_flip_left_out)
            .replace(R.id.container, newFragment)
            .commit();

    cardFlipped = !cardFlipped;
}
public static class CardBackFragment extends Fragment {

    public CardBackFragment() { }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView_back = inflater.inflate(R.layout.fragment_card_back, container, false);
        TextView textview_back = (TextView)rootView_back.findViewById(R.id.card_back);
        textview_back.setMovementMethod(new ScrollingMovementMethod());
        String text = getArguments().getString("back_text");
        textview_back.setText(text);

        return rootView_back;
    }
    static CardBackFragment newInstance(int position) {
        CardBackFragment cardBackFragment = new CardBackFragment();
        Bundle args = new Bundle();
        String card_front_string = card_activity.arraylst.get(position);
        String text = card_activity.deck_map.get(card_front_string);
        args.putString("back_text", text);
        cardBackFragment.setArguments(args);
        return cardBackFragment;
    }
}

public static class CardFrontFragment extends Fragment {

    public CardFrontFragment() { }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView_front = null;
        rootView_front = inflater.inflate(R.layout.fragment_card, container, false);
        TextView textview_front = (TextView)rootView_front.findViewById(R.id.card_front);
        String text = getArguments().getString("front_text");
        textview_front.setText(text);

        return rootView_front;
    }

    static CardFrontFragment newInstance(int position) {
        CardFrontFragment cardFrontFragment = new CardFrontFragment();
        Bundle args = new Bundle();
        String card_front_string = card_activity.arraylst.get(position);
        String text = card_front_string +" \n \n + \n Tap now to flip this card.";
        args.putString("front_text", text);
        cardFrontFragment.setArguments(args);
        return cardFrontFragment;
    }
}


 }
查看更多
登录 后发表回答