【问题标题】:save state of views in viewpager在 viewpager 中保存视图状态
【发布时间】:2013-11-27 10:02:30
【问题描述】:

这是对这个问题ViewPager and fragments — what's the right way to store fragment's state? 的跟进。我需要有人用代码解释这部分答案。

Another approach is to override FragmentPageAdapter.instantiateItem(View, int) and save a reference to the fragment returned from the super call before returning it (it has the logic to find the fragment, if already present).

我正在使用PagerAdapter 将数据从游标加载到浏览器中。我已经覆盖了PagerAdapter.intantiateItem。我所需要的只是能够保存被点击的按钮的状态。这是我的代码

    public class CustomQuestionPagerAdapter extends PagerAdapter {

private Cursor cursor;
private Cursor cursorCategory;
private LayoutInflater inflater;
private Context context;
private ArrayList<String> optionsArray; 
String rightAnswer;
String wrongAnswer1;
String wrongAnswer2;
Button option1;
Button option2;
Button option3;

public CustomQuestionPagerAdapter(Context context, Cursor cursor1, Cursor cursor2) {
    this.context = context;
    this.cursor = cursor1;
    this.cursorCategory = cursor2;
    this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}        

public void swapCursor(Cursor cursor) {
    this.cursor = cursor;
}

public void swapAnotherCursor(Cursor cursor) {
    this.cursorCategory = cursor;
}


public void destroyItem(View view, int position, Object object) {
    ((ViewPager) view).removeView((ScrollView) object);
}

@Override
public int getCount() {
    if (cursor == null) {
        return 0;
    }else {
        return cursor.getCount();
    }
}



/* (non-Javadoc)
 * @see android.support.v4.view.PagerAdapter#instantiateItem(android.view.View, int)
 */


@Override
public Object instantiateItem(View view, int position) {

    cursor.moveToPosition(position);
    final ViewPager pager = (ViewPager) view.findViewById(R.id.pager_nav);
    ScrollView layout = (ScrollView) inflater.inflate(R.layout.question_activity, null);
    if (cursorCategory != null && cursorCategory.moveToFirst()){
        String s = cursorCategory.getString(cursorCategory.getColumnIndex("name"));
        ((TextView)layout.findViewById(R.id.text_category)).setText(s);
    }

    Typeface tpf = Typeface.createFromAsset(context.getAssets(), "Roboto-Light.ttf");
    String text = cursor.getString(cursor.getColumnIndex("question_text"));
    TextView question_text =  (TextView)layout.findViewById(R.id.text_question);
    question_text.setText(text);
    question_text.setTypeface(tpf);

    String qPos = Integer.toString(position + 1) + ".";
    TextView question_position = (TextView) layout.findViewById(R.id.text_position);
    question_position.setText(qPos);
    question_position.setTypeface(tpf);

    this.rightAnswer = cursor.getString(cursor.getColumnIndex(DBHelper.RIGHT_ANSWER));
    this.wrongAnswer1 = cursor.getString(cursor.getColumnIndex(DBHelper.WRONG_ANSWER1));
    this.wrongAnswer2 = cursor.getString(cursor.getColumnIndex(DBHelper.WRONG_ANSWER2));

    optionsArray = new ArrayList<String>();
    optionsArray.clear();
    optionsArray.add(this.rightAnswer);
    optionsArray.add(this.wrongAnswer1);
    optionsArray.add(this.wrongAnswer2);
    Collections.shuffle(optionsArray);

    option1 = (Button) layout.findViewById(R.id.button_option1);
    option1.setText((CharSequence) this.optionsArray.get(0));

    option2 = (Button) layout.findViewById(R.id.button_option2);
    option2.setText((CharSequence) this.optionsArray.get(1));

    option3 = (Button) layout.findViewById(R.id.button_option3);
    option3.setText((CharSequence) this.optionsArray.get(2));


    final Button next = (Button) layout.findViewById(R.id.next_button);
    next.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            int j = getItem(+1) + 1;
            Toast.makeText(context, context.getResources().getString(R.string.question_no) + " " + j, Toast.LENGTH_SHORT).show();
            pager.setCurrentItem(getItem(+1), true);
            next.setBackgroundColor(0xffeeeeee); // i need to save this new bacground color
        }

        private int getItem(int i) {
            return i += pager.getCurrentItem();
        }
    });

我也试过这个答案,但没有用Saving Fragment state in ViewPager

提前致谢。

【问题讨论】:

  • 你不使用什么偏好来保存你想要的数据?

标签: android android-viewpager android-pageradapter


【解决方案1】:

PagerAdapter 不会自动保存和恢复状态恢复视图。
您需要等效于 FragmentStatePagerAdapter 但对于视图。 您可以选择是自己实现它还是扩展已经可用的组件。在 GitHub 上有一些:例如 https://github.com/NightlyNexus/ViewStatePagerAdapter.
如果您需要回收视图支架,甚至还有来自伟大的 Jake Wharton https://github.com/JakeWharton/salvage 的视图寻呼机适配器。 我已经使用了前者,因为它更适合我的情况,只需将您的 PageAdapter 替换为新的 ViewStatePagerAdapter 并覆盖 createView(ViewGroup, int)destroyView(ViewGroup, int)
检查这个例子真的很容易理解。

【讨论】:

    【解决方案2】:

    动态保存shared pref中被点击的button_id。您已经完成了所有操作,您需要从共享首选项中恢复按钮状态,并且当您单击任何按钮时,将按钮添加到共享首选项中。
    更新:

     public static final String PREFS_NAME = "MyPrefsFile";
     ------
    final Button next = (Button) layout.findViewById(R.id.next_button);
     SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
           boolean isClicked = settings.getBoolean(getCurrentItemPosition(), false);
            if(isClicked)
            {
            next.setBackgroundColor(0xffeeeeee);
            }
    
        next.setOnClickListener(new View.OnClickListener() {
    
            @Override
            public void onClick(View arg0) {
                int j = getItem(+1) + 1;
                Toast.makeText(context, context.getResources().getString(R.string.question_no) + " " + j, Toast.LENGTH_SHORT).show();
                pager.setCurrentItem(getItem(+1), true);
                 // i need to save this new bacground color
            SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
            SharedPreferences.Editor editor = settings.edit();
            editor.putBoolean(getCurrentItemPosition(), true);
            editor.commit();
            }
    
            private int getItem(int i) {
                return i += pager.getCurrentItem();
            }
        });
    

    getCurrentItemPosition() 是当前项目位置。

    【讨论】:

    • 如果我能得到一些代码,我将不胜感激。我了解 sharedPreferences 的概念,并且在项目的其他部分中使用过它,但我不知道如何获取每个视图的 button_id。谢谢。
    • 您拥有寻呼机 View_Id 和相应的 button_id-> 现在,当您将其保存到共享首选项时,以您的自定义格式(如 viewId_buttonId)保存,并且在恢复时如果 button_id 和 view_id 匹配则恢复。明白我的意思了吗?
    • 不幸的是,我没有。
    • 对您的代码进行一些修改后,它可以工作了。现在的问题是当按钮被单击时,它不会立即生效(直到用户在之前或之后滑动大约两个视图)然后返回该屏幕。如何解决?
    • 更新您的寻呼机适配器,以正确反映效果。
    猜你喜欢
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多