web-dev-qa-db-fra.com

Butterknife ne parvient pas à se lier à l'intérieur de ma classe d'adaptateur

J'ai un adaptateur qui dessine les dispositions de mon tiroir de navigation. Mon tiroir de navigation contient deux fichiers xml internes: l'un étant le Header et l'autre étant le Row. Je les dessine dans un seul adaptateur, mais lorsque j'essaie de setText() sur mon en-tête, je n'arrive pas à lier. Voici ma classe d'adaptateur:

public class DrawerAdapter extends RecyclerView.Adapter<DrawerAdapter.ViewHolder> {

private static final int HEADER_TYPE = 0;
private static final int ROW_TYPE = 1;
private static Context context;
private static DatabaseHelper databaseHelper;

private List<String> rows;
private List<Integer> icons;
private String driverName;

public DrawerAdapter(Context context, List<String> rows, List<Integer> icons, String driverName, DatabaseHelper databaseHelper) {
    this.icons = icons;
    this.rows = rows;
    this.context = context;
    this.driverName = driverName;
    this.databaseHelper = databaseHelper;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == HEADER_TYPE) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.drawer_header, parent, false);
        return new ViewHolder(view, viewType);

    } else if (viewType == ROW_TYPE) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.drawer_row, parent, false);
        return new ViewHolder(view, viewType);
    }
    return null;
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    if (holder.viewType == ROW_TYPE) {
        String rowText = rows.get(position - 1);
        int imageView = icons.get(position - 1);
        holder.textView.setText(rowText);
        holder.imageView.setImageResource(imageView);
    } else if (holder.viewType == HEADER_TYPE) {
        holder.driverNameText.setText(driverName);
    }
}

@Override
public int getItemCount() {
    return rows.size() + 1;
}

@Override
public int getItemViewType(int position) {
    if (position == 0)
        return HEADER_TYPE;
    return ROW_TYPE;
}

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    protected int viewType;
    @Bind(R.id.drawer_row_icon)
    ImageView imageView;
    @Bind(R.id.drawer_row_text)
    TextView textView;
    @Bind(R.id.drawer_row_id)
    FrameLayout listRow;
    @Bind(R.id.driverName)
    TextView driverNameText;

    public ViewHolder(View itemView, int viewType) {
        super(itemView);

        this.viewType = viewType;

        if (viewType == ROW_TYPE) {
            ButterKnife.bind(this, itemView);
            imageView.setOnClickListener(this);
            textView.setOnClickListener(this);
            listRow.setOnClickListener(this);
        } else {
            ButterKnife.bind(this, itemView);
        }
    }


 }

Comme vous pouvez le voir dans ma méthode onCreateViewHolder, je vérifie les deux viewType donc je sais quelle disposition dessiner. Cela créera à son tour un nouvel objet pour la classe ViewHolder dans lequel je "ESSAYER" de lier les éléments à l'intérieur de mon xml en fonction de viewType. Suis-je en train de manquer quelque chose ou de faire quelque chose de mal?

15
remedy.

J'ai pu résoudre ce problème en procédant comme suit:

Tout d'abord, les docs api ont déclaré ce qui suit

Par défaut, les vues doivent être présentes dans la présentation pour les liaisons de champ et de méthode. Si une vue est facultative, ajoutez une annotation @Nullable telle que celle de la bibliothèque de support-annotations.

@Nullable @Bind(R.id.title) TextView subtitleView;

http://jakewharton.github.io/butterknife/javadoc/

Maintenant que j'avais différents éléments à lier provenant de différents fichiers xml, je devais les étiqueter comme @Nullable car il est possible qu'ils ne soient même pas liables pour commencer. J'ai changé mon code pour faire ce qui suit:

@Nullable @Bind(R.id.drawer_row_icon)
ImageView imageView;
@Nullable @Bind(R.id.drawer_row_text)
TextView textView;
@Nullable @Bind(R.id.drawer_row_id)
FrameLayout listRow;
@Nullable @Bind(R.id.driverName)
TextView driverNameText;

Tout en déplaçant également la ButterKnife.bind() en dehors de mon bloc IF-ELSE.

25
remedy.

Vous vous engagez deux fois. Vous ne pouvez pas appeler bind deux fois sur la même vue. Il ne fait que vos appels findviewbyid. Appelez bind une fois au-dessus de votre bloc if.

public ViewHolder(View itemView, int viewType) {
    super(itemView);

    this.viewType = viewType;

    ButterKnife.bind(this, itemView);
    if (viewType == ROW_TYPE) {
        imageView.setOnClickListener(this);
        textView.setOnClickListener(this);
        listRow.setOnClickListener(this);
    }
}
6
doubleA