- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个带有 3 个选项卡的 ViewPager,每个选项卡加载一个 fragment ,同一个 fragment 类的新实例,但有一个额外的参数。
下面你可以找到 fragment 类,我在那个 fragment 中有一个 RecyclerView,当用户长按 RecyclerView 中的一个项目时,我试图打开一个上下文菜单。
我能够显示上下文菜单并获取单个 fragment 实例的所选项目的位置,当我滑动到下一个 fragment 时,我得到相同的索引位置,当我进一步调试时,我发现我我正在为前一个 fragment 的 RecyclerView 获取相同的适配器。这可以在我记录该 RecyclerView 的适配器大小时看到。
任何人都可以帮助我理解为什么当我在 ViewPager 中滑动到该 fragment 的一个完全不同的实例时,即使我可以在 fragment 中看到正确的数据并在onBindViewHolder
方法。
下面是 fragment 类的简化代码
public class HistoryFragment extends Fragment{
private static final String LOG_TAG = HistoryFragment.class.getSimpleName();
private RecyclerView mRecyclerView;
private HistoryAdapter mHistoryAdapter;
private List<Group> mGroups;
private String mGroupType;
/**
* tried using a static int value to track which context menu was opened and on which fragment
* refer post https://caughtinthemobileweb.wordpress.com/2013/10/22/android-viewpager-holds-reference-to-old-fragments/
* BUG LOGGED AT https://code.google.com/p/android/issues/detail?id=19211
* does not work :(
*/
/*private static int selectedContextMenu;*/ // returns valid index as int is static, but adapter still has old data
/**
* The fragment argument for this fragment.
*/
private static final String ARG_GROUP_TYPE = "group_type";
public HistoryFragment() { }
/**
* Returns a new instance of this fragment
*/
public static HistoryFragment newInstance(String groupType) {
HistoryFragment fragment = new HistoryFragment();
Bundle args = new Bundle();
args.putString(ARG_GROUP_TYPE, groupType);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_history, container, false);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerViewHistoryItem);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
mGroups = new ArrayList<>();
mHistoryAdapter = new HistoryAdapter(getActivity(), mGroups);
mRecyclerView.setAdapter(mHistoryAdapter);
Bundle bundle = getArguments();
mGroupType = bundle.getString(ARG_GROUP_TYPE);
if(mGroupType != null && !mGroupType.equals("")){
loadDataFromDb();
} else {
if(IS_DEBUG_ON) Log.d(LOG_TAG, "invalid fragment arguments");
getActivity().finish();
}
return rootView;
}
@Override
public boolean onContextItemSelected(MenuItem item){
// int id = item.getItemId();
Log.d(LOG_TAG, "position2: " + mHistoryAdapter.getSelectedItemPosition() +
" " + mGroups.get(mHistoryAdapter.getSelectedItemPosition()).getName()); // returns old data
Log.d(LOG_TAG, "size2: " + mHistoryAdapter.getItemCount()); // returns old data
// Log.d(LOG_TAG, "position3: " + selectedContextMenu); // returns correct index, but cant use as adapter still has old data
Log.d(LOG_TAG, "position4: " + ((HistoryAdapter) mRecyclerView.getAdapter()).getSelectedItemPosition()); // returns old data
return true;
}
private void loadDataFromDb(){
new LoadGroups().execute();
}
class HistoryAdapter extends RecyclerView.Adapter<HistoryFragment.HistoryAdapter.ViewHolder> {
private Context mContext;
private List<Group> mList;
private int mSelectedItemPosition;
HistoryAdapter(Context mContext, List<Group> mList) {
this.mContext = mContext;
this.mList = mList;
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener {
View mView;
TextView mTextViewName;
TextView mTextViewDescription;
ImageView mImageViewProfile;
ImageView mImageCheck;
public ViewHolder(View itemView) {
super(itemView);
this.mView = itemView;
this.mTextViewName = (TextView) itemView.findViewById(R.id.textViewGroupName);
this.mTextViewDescription = (TextView) itemView.findViewById(R.id.textViewGroupDescription);
this.mImageViewProfile = (ImageView) itemView.findViewById(R.id.groupImage);
this.mImageCheck = (ImageView) itemView.findViewById(R.id.imageCheck);
this.mView.setOnCreateContextMenuListener(this); // registering listener
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
if(mGroupType.equals(GroupContract.GroupEntry.GROUP_TYPE_HISTORY_GROUP)){
menu.add(Menu.NONE, R.id.action_resubscribed_group, Menu.NONE, R.string.action_resubscribed_group);
} else if(mGroupType.equals(GroupContract.GroupEntry.GROUP_TYPE_SUBSCRIBED_GROUP)){
if(!mList.get(getAdapterPosition()).isDefault()){
menu.add(Menu.NONE, R.id.action_unsubscribe_group, Menu.NONE, R.string.action_unsubscribe_group);
}
menu.add(Menu.NONE, R.id.action_mute, Menu.NONE, R.string.action_mute);
menu.add(Menu.NONE, R.id.action_view_group_info, Menu.NONE, R.string.action_view_group_info);
}
}
}
@Override
public HistoryAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.recycler_view_history, parent, false);
return new HistoryAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(final HistoryAdapter.ViewHolder holder, final int position) {
if(mGroupType.equals(GroupContract.GroupEntry.GROUP_TYPE_SUBSCRIBED_GROUP)){
holder.mImageCheck.setVisibility(View.VISIBLE);
} else {
holder.mImageCheck.setVisibility(View.GONE);
}
holder.mTextViewName.setText(mList.get(position).getName());
holder.mTextViewDescription.setText(mList.get(position).getDescription());
holder.mView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// mSelectedItemPosition = position; // tried this, returns correct
// selectedContextMenu = position; // also tried this, returns correct
mSelectedItemPosition = holder.getAdapterPosition(); // this also returns correct
Log.d(LOG_TAG, "position1 - onBind: " + mSelectedItemPosition + " "+ mList.get(mSelectedItemPosition).getName()); // returns correct data
return false;
}
});
}
@Override
public void onViewRecycled(ViewHolder holder) {
holder.mView.setOnLongClickListener(null); // clearing listener to avoid collision between list items
super.onViewRecycled(holder);
}
@Override
public int getItemViewType(int position) {
return 0;
}
@Override
public int getItemCount() {
return mList.size();
}
int getSelectedItemPosition() {
Log.d(LOG_TAG, "getter: " + mSelectedItemPosition); // this returns wrong data, shows that fragment is referring old adapter data
return mSelectedItemPosition;
}
}
// get data from db
class LoadGroups extends AsyncTask<Void, Void, Void>{
@Override
protected Void doInBackground(Void... voids) {
mGroups = GroupContract.getGroupEntriesFromDB(getActivity(), mGroupType);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mHistoryAdapter = new HistoryAdapter(getActivity(), mGroups);
mRecyclerView.setAdapter(mHistoryAdapter);
}
}
}
您可以在下面找到 ViewPager Adapter 类
public class HomeTabsPagerAdapter extends FragmentPagerAdapter {
private Context mContext;
HomeTabsPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return HistoryFragment.newInstance("TYPE_1");
case 1:
return HistoryFragment.newInstance("TYPE_2");
case 2:
return HistoryFragment.newInstance("TYPE_3");
}
return null;
}
@Override
public int getCount() {
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return mContext.getString(R.string.text_type_1);
case 1:
return mContext.getString(R.string.text_type_2);
case 2:
return mContext.getString(R.string.text_type_3);
}
return null;
}
// Doesn't work even when I use this or not
/*@Override
public int getItemPosition(Object object) {
// try http://stackoverflow.com/a/8024557
// return super.getItemPosition(object);
return POSITION_NONE;
}*/
}
最佳答案
我怀疑,使用 RecyclerView.LayoutManager 可能是个问题,因为您有一个静态类,前两个创建的 fragment 将具有相同的内容(第二个)。接下来的 fragment 也是如此。此外, getItemPosition(Object object) -> return POSITION_NONE 只能与 FragmentStatePagerAdapter 一起使用。 FragmentAdapter 一旦创建,您就永远不会更改 fragment 。 所以,我建议而不是:
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);mRecyclerView.setLayoutManager(layoutManager);
使用
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
//或改为设置 GridLayoutManager
如果您计划更新 fragment 的内容,请使用 FragmentStatePagerAdapter。
关于android - 即使 viewpager 正在显示另一个 fragment ,Recyclerview 适配器也会获取旧数据(适配器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43938788/
我有一个加号/减号按钮,希望用户不能选择超过 20 个但不知道如何让它工作。我尝试使用 min="1"max="5 属性,但它们不起作用。这是我的代码和一个 fiddle 链接。https://jsf
我正在尝试复制顶部底部图,如示例 here但它没有正确渲染(紫色系列有 +ve 和 -ve 值,绿色为负值)留下杂乱的人工制品。我也在努力创建一个玩具示例来复制这个问题,所以我希望尽管我缺乏数据,但有
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 已关闭 6 年前。 社区去年审查了是
这个问题在这里已经有了答案: Adding two positive integers gives negative answer.Why? (4 个答案) 关闭 5 年前。 我遇到了一个奇怪的问题
有谁知道如何将字符串值类型 -4,5 或 5,4 转换为 double -4.5 或 5.4? 最佳答案 只需使用 Double.parseDouble(Locale, String); 糟糕,我很困
我正在尝试根据 TextBlob 分类插入一个仅包含“正”或“负”字符串的新数据框列:对于我的 df 的第一行,结果是 ( pos , 0.75, 0.2499999999999997)我想要' 正
我对 VBA 非常陌生,无法理解如何在一个循环中完成 2 个任务。我非常感谢您的帮助。 我已经能够根据第 3 列中的数据更改第 2 列中的数值,但我不明白如何将负值的字体更改为红色。 表格的大小每月都
欢迎, 我正在使用 jquery 通过 POST 发送表单。 这就是我获得值(value)的方式。 var mytext = $("#textareaid").val(); var dataStrin
double d = 0; // random decimal value with it's integral part within the range of Int32 and always p
我有这个字符串: var a='abc123#xyz123'; 我想构建 2 个正则表达式替换函数: 1) 用 '*' 替换所有确实有 future '#'的字符(不包括'#') 所以结果应该是这样的
我正在使用 DialogFragment。当用户从 Gmail 平板电脑应用程序的屏幕与下面示例图片中的编辑文本进行交互时,我希望正面和负面按钮保持在键盘上方。 在我的尝试中不起作用,这是我的 Dia
从组装艺术一书中,我复制了这句话: In the two’s complement system, the H.O. bit of a number is a sign bit. If the H.O
是否有更好更优雅的方法来实现下面的简单代码(diffYear、A 和 B 是数字): diffYear = yearA - yearB; if (diffYear == 0) { A = B
我正在设计一种语言,并尝试确定 true 应该是 0x01 还是 0xFF。显然,所有非零值都将转换为 true,但我正在尝试确定确切的内部表示。 每种选择的优点和缺点是什么? 最佳答案 没关系,只要
在我的 dialogfragment 类的 OnCreateDialog 中,我正在这样做: AlertDialog.Builder builder = new AlertDialog.Builder
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda usin
我偶然发现了一个奇怪的 NSDecimalNumber 行为:对于某些值,调用 integerValue、longValue、longLongValue 等,返回意想不到的值(value)。示例: l
这个问题在这里已经有了答案: Resolving ambiguous overload on function pointer and std::function for a lambda using
我有这个正则表达式来测试用户输入是否有效: value.length === 0 || value === '-' || (!isNaN(parseFloat(value)) && /^-?\d+\.
我想用高斯混合模型拟合数据集,数据集包含大约 120k 个样本,每个样本有大约 130 个维度。当我使用 matlab 执行此操作时,我运行脚本(簇号为 1000): gm = fitgmdist(d
我是一名优秀的程序员,十分优秀!