To give an idea of what I am doing. I have a Main activity
that allows you to add names to a recyclerView
then start a round that sends to an Arraylist
of people through an Intent to CurrentMatchActivity
. after a while of user input it launches another instance of CurrentMatchActivity
by passing an Arraylist
of people to a new CurrentMatchActivity
.
想知道我在做什么。我有一个Main活动,允许您将名称添加到recyclerView然后开始一个回合,通过Intent to CurrentMatchActivity发送给人们的Arraylist。经过一段时间的用户输入后,它会通过将人员的Arraylist传递给新的CurrentMatchActivity来启动另一个CurrentMatchActivity实例。
Here is the Person class
这是Person类
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];
}
};
}
Here is the CurrentMatchActivity
这是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);
}
}
now the odd part is it works fine. unless I activate the code.
现在奇怪的部分是它工作正常。除非我激活代码。
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);
}
}
which causes a null
pointer crash in the MainAdapter
这导致MainAdapter中的空指针崩溃
The mainActivity
uses the mainAdapter
. but the currentMatchActivity
uses a CurrentMatch adapter.. And the crash happens when it tries to create an CurrentMatchActivity
from the CurrentMatchActivity
.
mainActivity使用mainAdapter。但currentMatchActivity使用CurrentMatch适配器..当它试图从CurrentMatchActivity创建CurrentMatchActivity时发生崩溃。
I don't believe that MainAdapter
should even be in use here... only CurrentMatchAdapter
. Furthermore... I don't see how activating the prepareMatch
function should affect the flow of my code in that way..
我不相信MainAdapter甚至应该在这里使用......只有CurrentMatchAdapter。此外...我没有看到如何激活prepareMatch函数应该以这种方式影响我的代码流。
Edit: found out that it was crashing because of because of the parcelable
. Guess it didn't like a person list inside of a person list.
编辑:发现它因为可分解而崩溃了。猜猜它不喜欢人名单中的人名单。
1 个解决方案
#1
-1
I came to the conclusion that the issue was nesting an arraylist of a class inside an arraylist of the same class and making it parcelable. I ended up using an arraylist of int primary keys inside of the class and it fixed the issue.
我得出的结论是,这个问题是在同一个类的一个arraylist中嵌入一个类的arraylist并使其可以分解。我最终在类中使用了int主键的arraylist并修复了问题。
Example:
class A implements parcelable {
arraylist<int> keys;
}
arraylist<a>
#1
-1
I came to the conclusion that the issue was nesting an arraylist of a class inside an arraylist of the same class and making it parcelable. I ended up using an arraylist of int primary keys inside of the class and it fixed the issue.
我得出的结论是,这个问题是在同一个类的一个arraylist中嵌入一个类的arraylist并使其可以分解。我最终在类中使用了int主键的arraylist并修复了问题。
Example:
class A implements parcelable {
arraylist<int> keys;
}
arraylist<a>