首页 文章

具有相同类的Parcelable嵌套writeTypedList

提问于
浏览
0

想知道我在做什么 . 我有一个 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 回答

  • -1

    我得出的结论是,这个问题是将一个类的arraylist嵌套在同一个类的arraylist中并使其可以分解 . 我最终在类中使用了int主键的arraylist并修复了问题 .

    例:

    class A implements parcelable {
          arraylist<int> keys;
    }
    
    
    arraylist<a>
    

相关问题