Android - 保持RecyclerView卡列表的状态

时间:2015-05-23 15:52:54

标签: android android-adapter android-recyclerview android-cardview

我对Android很新,我想创建一个带有一系列卡片的活动。这些卡中的每一张都有两个TextView:

  • 包含卡片文字的文件。

  • 另一个包含整数。

当我单击整数TextView时,我希望整数的值减小,直到达到零。

我实现了一个解决方案,但是我遇到了一个问题:当整数值减小时,屏幕旋转(例如横向)不会保留新值。

这是我的代码(我正在使用CardView和RecyclerView):

活动:

public class CardsActivity extends AppCompatActivity {

private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_cards);

    if (savedInstanceState != null) {
        int i = 0;
    }

    ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);

    mRecyclerView = (RecyclerView) findViewById(R.id.list_cards);

    mRecyclerView.setHasFixedSize(true);

    mLayoutManager = new LinearLayoutManager(this);
    mRecyclerView.setLayoutManager(mLayoutManager);

    Card[] myDataset ...// initialisation

    mAdapter = new CardsAdapter(myDataset);
    mRecyclerView.setAdapter(mAdapter);
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
}

@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_cards, 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);
}

适配器:

public class CardsAdapter extends RecyclerView.Adapter<CardsAdapter.ViewHolder> {
private Card[] mDataset;

// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    // each data item is just a string in this case
    public TextView cardText;
    public TextView cardCompteur;

    public ViewHolder(View v) {
        super(v);
        cardText = (TextView) v.findViewById(R.id.text);
        cardCompteur = (TextView) v.findViewById(R.id.counter);
        cardCompteur.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v instanceof TextView) {
            switch (v.getId()) {
                case R.id.compteur:
                    final CharSequence compteur = cardCompteur.getText();
                    int cpt = Integer.parseInt(compteur.toString());
                    int position = (int) cardCompteur.getTag();
                    if (cpt > 1) {
                        cpt--;
                        cardCompteur.setText(String.valueOf(cpt));
                    } else if (cpt == 1) {
                        // we deactivate
                        cpt--;
                        cardCompteur.setText(String.valueOf(cpt));
                        cardText.setTextColor(Color.GRAY);
                        cardCompteur.setTextColor(Color.GRAY);
                    }
            }
        }
    }
}

// Provide a suitable constructor (depends on the kind of dataset)
public CardsAdapter(Card[] myDataset) {
    mDataset = myDataset;
}

// Create new views (invoked by the layout manager)
@Override
public CardsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType) {
    // create a new view
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.activity_main, parent, false);
    // set the view's size, margins, paddings and layout parameters
    ViewHolder vh = new ViewHolder(v);
    return vh;
}

// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    // - get element from your dataset at this position
    // - replace the contents of the view with that element
    holder.cardText.setTag(position);
    holder.cardText.setText(mDataset[position].getText());
    holder.cardCompteur.setTag(position);
    holder.cardCompteur.setText(String.valueOf(mDataset[position].getCompteur()));
}

// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
    return mDataset.length;
}

}

活动XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="wrap_content" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".CardsActivity">

<android.support.v7.widget.RecyclerView
    android:id="@+id/list_cards"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

谢谢!

1 个答案:

答案 0 :(得分:0)

您需要使用here并将数据集保存在Bundle中。然后在onSaveInstanceState(Bundle outState)中,您将已保存的数据拉出来并执行您需要执行的操作。

这样的事情应该让你开始......

public class TestActivity extends AppCompatActivity {
    Card[] mCards;

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cards);

        // You put this here because onRestoreInstanceState won't be called on activity creation
        if (savedInstanceState != null) {
            mCards = savedInstanceState.getParcelable("myCards");
        }
    }

    @Override
    protected void onRestoreInstanceState(final Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        // This is here because if you are recreating after an orientation change, for example, onCreate won't be called
        if (savedInstanceState != null) {
            mCards = savedInstanceState.getParcelable("myCards");
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        // You need to probably check for null here
        mAdapter = new CardsAdapter(mCards);
        mRecyclerView.setAdapter(mAdapter);
    }

    @Override
    protected void onSaveInstanceState(final Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putParcelableArray("myCards", mCards);
    }
}

在您的Card类中,您需要实现Parcelable ...

public class Card implements Parcelable {
    private String text;

    private int count;

    public Card(String text, int count) {
        this.text = text;
        this.count = count;
    }

    // Some getters and possibly setters

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(final Parcel dest, final int flags) {
        dest.writeString(this.text);
        dest.writeInt(this.count);
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public Card createFromParcel(Parcel in) {
            return new Card(in.readString(), in.readInt());
        }

        @Override
        public Card[] newArray(final int size) {
            return new Card[size];
        }
    };
}