了解我在做什么。我有一个Main activity
,允许您为recyclerView
添加名称,然后开始一轮通过意图发送给Arraylist
人CurrentMatchActivity
。在用户输入一段时间后,它会通过将CurrentMatchActivity
人传递给新的Arraylist
来启动另一个CurrentMatchActivity
实例。
以下是Person class
public class Person implements Parcelable {
private String name;
private int wins;
private long totalWins;
private boolean stillPlaying;
private ArrayList<Person> previousOpponents;
Person(String name)
{
this.name = name;
wins = 0;
totalWins = 0;
stillPlaying = true;
previousOpponents = new ArrayList<>();
}
public void setStillPlaying(boolean playing)
{
stillPlaying = playing;
}
public void addOpponent(Person person) {
previousOpponents.add(person);
}
public boolean hasFought(Person person) {
return previousOpponents.contains(person);
}
@Override
public int describeContents() {
return 0;
}
private Person(Parcel in)
{
name = in.readString();
wins = in.readInt();
totalWins = in.readLong();
stillPlaying = (boolean) in.readValue(null);
previousOpponents = new ArrayList<>();
in.readTypedList(previousOpponents, null);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(wins);
dest.writeLong(totalWins);
dest.writeValue(stillPlaying);
dest.writeTypedList(previousOpponents);
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
public Person createFromParcel(Parcel in) {
return new Person(in);
}
public Person[] newArray(int size) {
return new Person[size];
}
};
}
以下是CurrentMatchActivity
package omarzious.myapplication;
public class CurrentMatchActivity extends Activity {
private ArrayList<Person> people;
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private int round;
private RetainedFragment dataFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_current_match);
FragmentManager fm = getFragmentManager();
dataFragment = (RetainedFragment) fm.findFragmentByTag("currentMatchData");
if (dataFragment == null){
dataFragment = new RetainedFragment();
fm.beginTransaction().add(dataFragment, "currentMatchData").commit();
round = getIntent().getIntExtra("round",1);
people = getIntent().getParcelableArrayListExtra("people");
prepareMatch();
}
else
{
people = dataFragment.getData();
}
this.setTitle(getString(R.string.round)+" "+round);
mRecyclerView = (RecyclerView) findViewById(R.id.current_match_recycler_view);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new CurrentMatchAdapter(people, getApplicationContext());
mRecyclerView.setAdapter(mAdapter);
// Swipe Portion
SwipeableRecyclerViewTouchListener swipeTouchListener = new SwipeableRecyclerViewTouchListener(mRecyclerView,
new SwipeableRecyclerViewTouchListener.SwipeListener() {
private int personIndex;
@Override
public boolean canSwipe(int position)
{
if (position == (int)people.size()/2)
{
return false;
}
return people.get(position*2).isStillPlaying();
}
@Override
public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions)
{
personIndex = position*2;
//personBeat(personIndex, personIndex+1);
people.get(personIndex).won();
mAdapter.notifyItemChanged(position);
// if player on right won
if (people.get(personIndex).isWinner())
{
people.get(personIndex).setStillPlaying(false);
people.get(personIndex+1).setStillPlaying(false);
if (checkForRoundEnd())
{
startNewRound();
}
}
}
mAdapter.notifyDataSetChanged();
}
public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
personIndex = position*2+1;
people.get(personIndex).won();
mAdapter.notifyItemChanged(personIndex);
// if player on left won
if (people.get(personIndex).isWinner())
{
people.get(personIndex).setStillPlaying(false);
people.get(personIndex-1).setStillPlaying(false);
if (checkForRoundEnd())
{
startNewRound();
}
}
}
mAdapter.notifyDataSetChanged();
}
});
mRecyclerView.addOnItemTouchListener(swipeTouchListener);
}
public void checkForRematches()
{
int i = 0;
Person personA;
Person personB;
ListIterator<Person> a;
boolean collision = false;
int numberOfItterations = 0;
// do {
a = people.listIterator();
collision = false;
i=0;
while ( i < (int)(people.size() / 2))
{
personA = a.next();
personB = a.next();
i++;
if (personA.hasFought(personB)) {
a.remove();
a.add(personB);
people.add(personB);
collision = true;
Toast.makeText(this,"WTF", Toast.LENGTH_SHORT);
}
}
numberOfItterations++;
// } while(collision);
Toast.makeText(this, "prepare match had to itterate "+numberOfItterations+ "times", Toast.LENGTH_SHORT).show();
}
public void prepareMatch() {
Collections.shuffle(people);
int i = 0;
Person personA;
Person personB;
ListIterator<Person> a = people.listIterator();
if (round > 1)
{
// checkForRematches();
}
while (i < (int)(people.size() / 2))
{
personA = a.next();
personB = a.next();
i++;
personA.addOpponent(personB);
personB.addOpponent(personA);
}
}
public boolean checkForRoundEnd()
{
int stillPlayingAllowed = people.size() % 2;
int peopleStillPlaying = 0;
for (Person person : people) {
if (person.isStillPlaying()) {
peopleStillPlaying++;
}
}
return peopleStillPlaying == stillPlayingAllowed;
}
public void startNewRound()
{
Iterator<Person> i = people.iterator();
Person person;
while (i.hasNext()) {
person = i.next();
if (!person.isWinner() && !person.isStillPlaying())
{
i.remove();
}
person.clearWins();
person.setStillPlaying(true);
}
if (people.size() > 1) {
Toast.makeText(this, "Starting new round", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, CurrentMatchActivity.class);
intent.putExtra("round",++round);
intent.putParcelableArrayListExtra("people", people);
startActivity(intent);
}
else
{
Intent intent = new Intent(this, GameOverActivity.class);
intent.putParcelableArrayListExtra("people", people);
startActivity(intent);
}
}
@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_current_match, 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);
}
@Override
public void onDestroy()
{
super.onDestroy();
dataFragment.setData(people);
}
}
现在奇怪的部分是它工作正常。除非我激活代码。
public void prepareMatch() {
Collections.shuffle(people);
int i = 0;
Person personA;
Person personB;
ListIterator<Person> a;
while (i < (int)(people.size() / 2))
{
personA = a.next();
personB = a.next();
i++;
personA.addOpponent(personB);
personB.addOpponent(personA);
}
}
会导致null
MainAdapter
指针崩溃
mainActivity
使用mainAdapter
。但是currentMatchActivity
使用了CurrentMatch适配器..当它尝试从CurrentMatchActivity
创建CurrentMatchActivity
时发生崩溃。
我不相信MainAdapter
甚至应该在这里使用......只有CurrentMatchAdapter
。此外......我不知道如何激活prepareMatch
函数会以这种方式影响我的代码流。
编辑:因为parcelable
而发现它崩溃了。猜猜它并不像人名单中的人名单。
答案 0 :(得分:-1)
我得出的结论是,问题是将一个类的arraylist嵌套在同一个类的arraylist中并使其可分辨。我最终在类中使用了int主键的arraylist并解决了这个问题。
示例:
class A implements parcelable {
arraylist<int> keys;
}
arraylist<a>