交换卡片时无法更新片段文本
Posted
技术标签:
【中文标题】交换卡片时无法更新片段文本【英文标题】:Not able to Update fragments text while swaping cards 【发布时间】:2017-05-17 19:47:12 【问题描述】:我正在开发卡片刷卡和卡片翻转功能,我正在使用 ViewPager 和 Fragments。
我的问题是当我从左到右或从右到左刷卡时,我无法更新片段内的 TextView,但是当我翻转卡时它会更新 UI。 我尝试了互联网上可用的一切,但没有一个解决方案对我有用。
我正在关注此链接https://github.com/jamesmccann/android-view-pager-cards
这是我的代码
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;
这是我的适配器代码
@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;
请让我知道我在这里做错了什么。
提前致谢
【问题讨论】:
不要使用静态字段CardActivity.mViewPager
。见developer.android.com/guide/components/…
@suneel 您能否详细说明您的问题(使用您的应用程序、xml 或其他内容的一些屏幕截图)?我无法理解确切的问题。
@TdSoft 我附上了一些截图并更新了我的问题,请看一下。
【参考方案1】:
我终于能够通过一些努力做到这一点。
经过搜索,我知道getItems
(CardPagerAdapter
中的方法)被调用了两次,因为Android为平滑过渡创建了一个额外的片段,而我从getItems
发送或获取了错误的片段位置。
通过让机器人创建一个额外的片段并发送正确的位置,我能够解决这个问题。
这是我更新的代码
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;
【讨论】:
我很高兴你能回答你自己的问题@suneel。干得好! 非常感谢。【参考方案2】:正如@david-rawson 所说
不要使用静态字段 CardActivity.mViewPager。见https://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
这样做的原因是 ViewPager 可能/将在您的片段显示之前创建它们的视图,以确保您获得人们喜欢 ViewPager 的流畅动画。所以mViewPager
同时调用了多个片段createView()函数,此时mViewPager
有一个.getCurrentItem()
的索引,该索引指向正在查看的页面上的CardContainer。
更好的选择是传递CardContainerFragment
带有“completeText”值的字符串参数,您希望它在创建CardBackFragment
或CardFrontFragment
时显示该参数。
通过this了解更多详情。
【讨论】:
【参考方案3】:您只需将数据设置为 CardFrontFragment 中使用的文本视图。 每当发生滑动时,就会调用 CardContainerFragment 的 onCreateView() 。 每次调用 onCreateView() 时,您都在添加 CardFrontFragment。您需要使用 CardFrontFragment 的文本视图,而不是使用活动的文本视图。
只需替换CardActivity.tv.setText(current_page);
textView.setText(current_page);
确保您在 CardFrontFragment 中使用的 textview 在类级别可用。
您使用的是静态片段,因此 textview 必须是静态的。
private static TextView textView=null;
希望这对你有用:)
【讨论】:
【参考方案4】:你试过了吗:
tv.post(new Runnable()
@Override
public void run()
CardActivity.tv.setText(current_page);
);
【讨论】:
【参考方案5】:我在我的应用程序中做了类似的事情,我使用开关盒管理我的 TextView 到 OnCreateView 中的显示。
我试图实现你的代码,但没有你的所有材料(如自定义动画师)。
然后你应该尝试这样的事情:
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;
textview显示在您的页面上,并在选择更改时,将更改TextView的内容。
【讨论】:
如果您可以查看我的代码,是否可以。我可以给您访问权限。以上是关于交换卡片时无法更新片段文本的主要内容,如果未能解决你的问题,请参考以下文章
片段 TextView 无法从 parcelable 对象更新