How to use an array inside getView in an adapter?

1

This is my problem, I'm passing a sequence of arrays to an adapter that should be placed inside a listview, of which I have a two-dimensional array called materials:

public View onCreateView(...){
...
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    // Meus arrays que vão dentro do array bidimensional
    int[] mat1 = new int[]{R.drawable.bronze};
    int[] mat2 = new int[]{R.drawable.prata};
    int[] mat3 = new int[]{R.drawable.ouro};

    int[] imagens = new int[]{R.drawable.adaga, R.drawable.espada, R.drawable.machado};
    String[] nomes = new String[]{"Adaga", "Espada", "Machado"};
    int[][] materiais = new int[][]{mat1, mat2, mat3}; // Meu array bidimensional.
    String[] desc = new String[]{"Uma adaga", "Uma espada", "Um machado"};
    int[] cores = getActivity().getResources().getIntArray(R.array.cores);

    ListView listView = (ListView) getActivity().findViewById(R.id.menuFerreiroMateriaisListView);
    listView.setAdapter(new FragFerreiroArrayAdapter(getActivity(), imagens, nomes, materiais, desc, cores));

    super.onActivityCreated(savedInstanceState);
}

The custom adapter that receives the arrays is this, the idea is to create a list of items (in my case, a dagger, a sword and an ax), where each one has a name, an image, a description and a list of icons that would be the materials used to create that item:

public class FragFerreiroArrayAdapter extends BaseAdapter {

private final String TAG = "FragFerreiro";

private final List<Item> mItems = new ArrayList<Item>();
private final LayoutInflater mInflater;
private final Context context;

// Este é o construtor chamado que recebe o array bidimensional da class anterior
public FragFerreiroArrayAdapter(Context context, int[] imagens, String[] nomes, int[][] materiais, String[] desc, int[] cores) {
    this.context = context;
    mInflater = LayoutInflater.from(this.context);

    //int[] teste = new int[] {R.drawable.bronze};

    // Aqui eu crio um novo objeto item que vai ser
    // referente a uma linha dentro do meu layout,
    // repare que ele recebe o valor de array materiais[]
    // que é na verdade um array de int definido na classe
    // anterior.
    for (int i = 0; i < imagens.length; i++) {
        mItems.add(new Item(imagens[i], nomes[i], materiais[i], desc[i], cores[i]));
        //mItems.add(new Item(imagens[i], nomes[i], teste, desc[i], cores[i]));
    }

}

@Override
public int getCount() {
    return mItems.size();
}

@Override
public Item getItem(int i) {
    return mItems.get(i);
}

@Override
public long getItemId(int i) {
    // TODO verificar esse mêtodo
    return mItems.get(i).imagem;
}

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
    View v = view;
    ImageView imagemItem;
    TextView nomeItem;
    LinearLayout materiaisItem;
    TextView descricaoItem;

    if (v == null) {
        v = mInflater.inflate(R.layout.menu_ferreiro_frag_materiais_item_imagem, viewGroup, false);
        v.setTag(R.id.menu_ferreiro_frag_materiais_item_imagem, v.findViewById(R.id.menu_ferreiro_frag_materiais_item_imagem));
        v.setTag(R.id.menu_ferreiro_frag_materiais_item_nome, v.findViewById(R.id.menu_ferreiro_frag_materiais_item_nome));
        v.setTag(R.id.menu_ferreiro_frag_materiais_item_materiais_necessarios, v.findViewById(R.id.menu_ferreiro_frag_materiais_item_materiais_necessarios));
        v.setTag(R.id.menu_ferreiro_frag_materiais_item_descricao, v.findViewById(R.id.menu_ferreiro_frag_materiais_item_descricao));
    }

    Item itemAtual = getItem(i);

    imagemItem = (ImageView) v.getTag(R.id.menu_ferreiro_frag_materiais_item_imagem);
    imagemItem.setImageResource(itemAtual.imagem);

    nomeItem = (TextView) v.getTag(R.id.menu_ferreiro_frag_materiais_item_nome);
    nomeItem.setText(itemAtual.nome);

    // Este é um linear layout envolvido em um horizontal scroll view que deve receber uma lista de ícones.
    materiaisItem = (LinearLayout) v.getTag(R.id.menu_ferreiro_frag_materiais_item_materiais_necessarios);

    // Esta parte do código está dando MUITA dor de cabeça.
    for(int e=0;e<itemAtual.materiais.length;e++)
    {
        ImageView imagem = new ImageView(context);
        imagem.setImageResource(itemAtual.materiais[e]);
        materiaisItem.addView(imagem);
    }

    descricaoItem = (TextView) v.getTag(R.id.menu_ferreiro_frag_materiais_item_descricao);
    descricaoItem.setText(itemAtual.descricao);

    // TODO adicionar cor de fundo

    return v;
}

private static class Item {
    public final int imagem;
    public final String nome;
    int[] materiais;
    public final String descricao;
    public final int cor;
    private final String TAG = "Item";

    Item(int imagem, String nome, int[] materiais, String descricao, int cor) {
        this.imagem = imagem;
        this.nome = nome;
        this.materiais = materiais;
        this.descricao = descricao;
        this.cor = cor;
    }
}
}

The list is created correctly as expected and the rows are added correctly:

However,inthispartofthecode,forsomereasonitdefinesthefirstlinewithalltheiconspassedbyarraymaterialsascanbeseenabove,wherethereshouldbeonlyoneimageofa"copper", there are 2 images of copper and plus 1 silver and one gold:

    for(int e=0;e<itemAtual.materiais.length;e++)
    {
        ImageView imagem = new ImageView(context);
        imagem.setImageResource(itemAtual.materiais[e]);
        materiaisItem.addView(imagem);
    }

I've tried to check the source of the problem by putting text outputs to the log at each step by counting the array values and printing them out. I'm really out of ideas, I made this little project exactly to learn how to use custom adapters but for what it seems to me, I stopped in a very silly mistake and I can not solve it.

This is the XML of the item created in the custom adapter:

<ImageView
    android:id="@+id/menu_ferreiro_frag_materiais_item_imagem"
    android:layout_width="100sp"
    android:layout_height="100sp"
    android:clickable="false" />

<RelativeLayout
    android:id="@+id/menu_ferreiro_frag_materiais_item_conteudo_interno"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/menu_ferreiro_frag_materiais_item_imagem"
    android:layout_alignParentTop="true"
    android:layout_toEndOf="@+id/menu_ferreiro_frag_materiais_item_imagem"
    android:layout_toRightOf="@+id/menu_ferreiro_frag_materiais_item_imagem"
    android:clickable="false"
    android:orientation="vertical">

    <TextView
        android:id="@+id/menu_ferreiro_frag_materiais_item_nome"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="false"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/menu_ferreiro_frag_materiais_item_descricao"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/menu_ferreiro_frag_materiais_item_nome"
        android:clickable="false"
        android:textSize="20sp"
        />

    <HorizontalScrollView
        android:layout_below="@id/menu_ferreiro_frag_materiais_item_descricao"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <LinearLayout
            android:id="@+id/menu_ferreiro_frag_materiais_item_materiais_necessarios"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"/>

    </HorizontalScrollView>

</RelativeLayout>

<Button
    android:id="@+id/menu_ferreiro_frag_materiais_item_botao_criar"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_alignEnd="@+id/menu_ferreiro_frag_materiais_item_conteudo_interno"
    android:layout_alignParentTop="true"
    android:layout_alignRight="@+id/menu_ferreiro_frag_materiais_item_conteudo_interno"
    android:text="Criar" />

    
asked by anonymous 04.12.2015 / 05:48

1 answer

0

Ok,

I discovered the problem, as it is possible to perceive by the methods used this class is a Fragment that is inflated in an Activity:

public View onCreateView(...){
...
}

@Override
public void onActivityCreated(...) {
...
}

This is the activity that receives the class above, notice that it has as the view the menu_ferreiro_activity:

public class MenuFerreiro extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.menu_ferreiro_atividade);
        .
        .
        .
    }
}

This is the XML in question, it has a framelayout used only to be replaced by the Fragment selected by the user:

<LinearLayout
    ...>

    <Button
        ... />

    <Button
        ... />

    <Button
       ... />

</LinearLayout>

<FrameLayout
    android:id="@+id/menuFerreiroFrameLayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

</LinearLayout>

It seems to me that because I'm using "wrap_content" the Fragment was being rendered 2 times because the application did not have the exact size of the screen, which meant that all the images were placed on the first line in the first rendering and only after execution as expected. I changed from "wrap_content" to "fill_parent" and the screen started to be rendered only once, resulting in the screen:

Summary : When using getView on an adapter, remember that it will be called more than once if the parent view of the view you're moving has layout_height and layout_width as wrap_content , what's worth is the main view and not necessarily the view that gets what you're trying to inflate.

    
04.12.2015 / 17:19