6

私はAndroidを初めて使用し、プロジェクトに取り組んでおり、ニュースフィードページにモジュラーフィードRecyclerViewを含めようとしています。これは、質問の種類に応じてさまざまな回答フォームで質問を表示します。これまで私が行っていた方法は、インクルードを使用し、必要に応じてフォームを表示することでした。最近、モジュールを追加してから、アプリの速度が大幅に低下し始めたので、ViewStubs を実装しようとしています。

これは私の RecyclerView アダプターです。

public class ReQuestionAdapter extends RecyclerView.Adapter<FeedItem> {
private ArrayList<Question> myQuestions;
public ReQuestionAdapter(Context context, ArrayList<Question> questions) {
    myQuestions = questions ;
}

@Override
public FeedItem onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.list_item_re_question, parent, false);
    return new FeedItem(view);
}

@Override
public void onBindViewHolder(FeedItem holder, int position) {
    Question q = myQuestions.get(position);
    holder.bindQuestion(q);
}

@Override
public int getItemViewType(int position) {
    return 0;
}

@Override
public int getItemCount() {
    return myQuestions.size();
}
}

これは、アダプターの ViewHolder クラスです。

public class FeedItem extends RecyclerView.ViewHolder{
private Question mQuestion;
public TextView tvName;
public TextView tvTime;
public TextView tvContent;
public ProfilePictureView profilePictureView;
public ViewStub moduleView;
private int moduleType;

public FeedItem(View itemView) {
    super(itemView);

}

public void bindQuestion(Question question) {
    mQuestion = question;
    tvTime = (TextView) itemView.findViewById(R.id.li_q_date);
    tvContent = (TextView) itemView.findViewById(R.id.li_q_content);
    moduleView = (ViewStub) itemView.findViewById(R.id.module_viewstub);
    tvTime.setText(TimeHandler.When(mQuestion.publish_time));
    tvContent.setText(mQuestion.content);
    moduleType = question.type;
        switch (moduleType) {
            case Question.TYPE_YN:
                moduleView.setLayoutResource(R.layout.module_yes_no);
                moduleView.inflate();
                break;
            case Question.TYPE_CUSTOM:
                moduleView.setLayoutResource(R.layout.module_custom);
                moduleView.inflate();
                break;
            default:
                break;
        }
    }
}

ここでの問題は、特定のレイアウトを含む ViewStub を新しいもので再膨張できないことです。その理由は、画面を離れるとすぐにビュー階層から削除されるためです。症状: RecyclerView、画面を埋める最初のリスト項目は完璧に機能していますが、前の項目が画面を離れたときに他の項目が読み込まれると、FeedItem バインディングでNullPointerExceptionが発生します。(リスト項目のレイアウトでは見つかりません)。

ViewStubs と同じくらい効率的なソリューション、またはそれらを適切に機能させる方法を探しています。多くのモジュールを取得し、各項目でそれらをすべて非表示にするとアプリが遅くなるからです。

4

1 に答える 1

7

メソッドでは、bindQuestion()2 つの異なるレイアウトを参照して膨張させるため、本質的に 2 つの異なるビュー タイプがあります。

アダプター ビューには、この組み込みを効率的に処理する方法があります。

オーバーライドすることから始めますgetItemViewType()。のアイテムがレイア​​ウトをposition取得したmodule_yes_no場合は 0 を返しmodule_customます。レイアウトを取得した場合は 1 を返します。

次に でonCreateViewHolder()、パラメータが 0 の場合、レイアウトを備えたビューviewTypeを膨張させます。== 1 の場合、ビューのバージョンをインフレートします。list_item_re_questionmodule_yes_noviewTypemodule_custom

でビューを取得すると、正しいサブビューonBindViewHolder()既にあるため、必要に応じてそのビューに入力します。を使用することgetItemViewType()で、RecyclerViewはユーザーと協力して、必要な正確なビューをリサイクルします。

forとfor の 2 つのFeedItemサブクラスを持つこともできるので、では と のクラスをチェックし、それに応じて分岐します。module_yes_nomodule_customonBindViewHolder()ViewHolder

これにより、アプリのパフォーマンスが向上するはずです。

于 2015-07-24T12:07:53.427 に答える