想知道我在做什么 . 我有一个 Main activity
,允许你为 recyclerView
添加名称然后开始一轮通过Intent发送给 Arraylist
的人到 CurrentMatchActivity
. 在用户输入一段时间后,它会通过将 Arraylist
个人传递给新的 CurrentMatchActivity
来启动 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);
}
}
导致 MainAdapter
指针崩溃 MainAdapter
mainActivity
使用 mainAdapter
. 但 currentMatchActivity
使用CurrentMatch适配器..当它试图从 CurrentMatchActivity
创建 CurrentMatchActivity
时发生崩溃 .
我不相信 MainAdapter
甚至应该在这里使用......只有 CurrentMatchAdapter
. 此外...我没有看到激活 prepareMatch
函数应该如何以这种方式影响我的代码流 .
编辑:发现因为 parcelable
而崩溃了 . 猜猜它不喜欢人名单中的人名单 .
1 回答
我得出的结论是,这个问题是将一个类的arraylist嵌套在同一个类的arraylist中并使其可以分解 . 我最终在类中使用了int主键的arraylist并修复了问题 .
例: