Daniel Santos
Daniel Santos

Reputation: 85

How update ListView from my Custom Adapter

I just wanna update my ListView, but I cant. I dont know what. What did I do Wrong? I guess that the Adapter that I created is missing something to return the real adapter that I can handle.

Home.java (MainActivity)

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
    BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    MenuItem item = navigation.getMenu().findItem(R.id.navigation_home);
    item.setCheckable(true);
    item.setChecked(true);
    BoxStore boxStore = AppMain.getBoxStore();
    equipamentoBox = boxStore.boxFor(Equipamento.class);
    lancamentoBox = boxStore.boxFor(Lancamento.class);

    loadObjects();

       ////FOCUS HERE/////------------------------------
    List<Equipamento> equipamentos = new ArrayList<>();
    EquipamentoAdapter adapter;adapter = new EquipamentoAdapter(this, equipamentos);
    listEquipamentos = (ListView) findViewById(R.id.listEquipamentos);
    listEquipamentos.setAdapter(adapter);

    registerForContextMenu(listEquipamentos);



}

EquipamentoAdapter.JAVA

public class EquipamentoAdapter extends ArrayAdapter<Equipamento> {
private final Activity context;
private final List<String> idArray = new ArrayList<String>();
private final List<String> qtdArray = new ArrayList<String>();
private final ArrayList<String> nomeArray = new ArrayList<String>();
private List<Equipamento> equipamentos = new ArrayList<>();

public EquipamentoAdapter(Activity context, List<Equipamento> equipamentos) {
    super(context, R.layout.listview_row, equipamentos);
    for (Iterator iterator = equipamentos.iterator(); iterator.hasNext(); ) {
        Equipamento equipamento = (Equipamento) iterator.next();
        this.idArray.add(Integer.toString((int)equipamento.getId()));
        this.qtdArray.add(Integer.toString(equipamento.getQuantidade()));
        this.nomeArray.add(equipamento.getNome());
    }
    this.context = context;
    this.equipamentos = equipamentos;
}

public void callDialogTransaction(Equipamento equipamento) {
    AlertDialog.Builder mBuilder = new AlertDialog.Builder(getContext());
    LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );

    View mView = inflater.inflate(R.layout.dialog_lancamento,null);
    TextView title = (TextView) mView.findViewById(R.id.txtTitle);
    final EditText quantidade = (EditText) mView.findViewById(R.id.edtQtd);
    final EditText Observacao = (EditText) mView.findViewById(R.id.edtObs);
    Button addTransaction = (Button) mView.findViewById(R.id.btnAddTranD);
    title.setText(equipamento.getNome());

    addTransaction.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View view) {
            if(!quantidade.getText().toString().isEmpty()){
                Toast.makeText(getContext(), "Success!", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getContext(), "Erro. Fill everything.", Toast.LENGTH_SHORT).show();
            }
        }
    });

    mBuilder.setView(mView);
    AlertDialog dialog = mBuilder.create();
    dialog.show();
}

public View getView(final int position, View view, ViewGroup parent) {
    LayoutInflater inflater = context.getLayoutInflater();
    View rowView = inflater.inflate(R.layout.listview_row,null,true);

    //this code gets references to objects in the listview_row.xml file
    TextView txtQtd,txtName;
    txtQtd = (TextView) rowView.findViewById(R.id.txtQtd);
    txtName = (TextView) rowView.findViewById(R.id.txtName);
    final ImageButton btnAddTransaction = (ImageButton) rowView.findViewById(R.id.btnAddTransaction);

    //this code sets the values of the objects to values from the arrays
    txtQtd.setText(qtdArray.get(position));
    txtName.setText(nomeArray.get(position));

    btnAddTransaction.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Equipamento equipamento = equipamentos.get(position);
            callDialogTransaction(equipamento);
            Animation animation = new AlphaAnimation(1.0f,0.8f);
            animation.setDuration(100);
            btnAddTransaction.startAnimation(animation);
        }
    });
    return rowView;
}

}

I read that I could try to use adapter.notifyDataSetChanged(); but its not working. Also I tryed to add this on EquipamentoAdapter.java and call from my MainActivity when I needed to refresh, but it didn work as well. I dont know why. Everything seems right.

public void refreshData(){
    this.equipamentos.clear();
    for(Equipamento equipamento : equipamentoBox.getAll()){
        this.equipamentos.add(equipamento);
    }

    notifyDataSetChanged();
}

Upvotes: 0

Views: 64

Answers (5)

Akinola Olayinka
Akinola Olayinka

Reputation: 861

I'll suggest the following changes:

  1. Reference the equipamento object directly from List inside the getView the so that the getView function becomes

    public View getView(final int position, View view, ViewGroup parent) {
        LayoutInflater inflater = context.getLayoutInflater();
        View rowView = inflater.inflate(R.layout.listview_row,null,true);
    
        //this code gets references to objects in the listview_row.xml file
        TextView txtQtd,txtName;
        txtQtd = (TextView) rowView.findViewById(R.id.txtQtd);
        txtName = (TextView) rowView.findViewById(R.id.txtName);
        final ImageButton btnAddTransaction = (ImageButton) rowView.findViewById(R.id.btnAddTransaction);
    
        //this code sets the values of the objects to values from the arrays
    
        Equipamento equipamento = equipamentos.get(position);
    
        txtQtd.setText(String.valueOf(equipamento.getId()));
        txtName.setText(String.valueOf(equipamento.getQuantidade()));
    
        btnAddTransaction.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Equipamento equipamento = equipamentos.get(position);
            callDialogTransaction(equipamento);
            Animation animation = new AlphaAnimation(1.0f,0.8f);
            animation.setDuration(100);
            btnAddTransaction.startAnimation(animation);
        }
    });
        return rowView;
    

    }

  2. Set the Items count with the getCount method

    public int getCount(){ return equipamentos.size(); }

with these, calling notifyDataSetChanged(); should update the list without need to reinitialize the adapter.

Upvotes: 1

Krishna Lohiya
Krishna Lohiya

Reputation: 11

As your following logic is in constructor of adapter-

enter code here
for (Iterator iterator = equipamentos.iterator(); iterator.hasNext(); ) {
   Equipamento equipamento = (Equipamento) iterator.next();
   this.idArray.add(Integer.toString((int)equipamento.getId()));
   this.qtdArray.add(Integer.toString(equipamento.getQuantidade()));
   this.nomeArray.add(equipamento.getNome());
   }

after notifyDataSetChange, adapter is not called so you can do 2 things - 1) Initialize the Adapter as @Gastón Saillén answered. 2) Put that in some method and call it before you call notifydatasetchange.

Upvotes: 0

davisjp
davisjp

Reputation: 789

Create a method to replace the data and check the size of your adapter after you add new elements.

Add something like this to the adapter:

public void replaceData(List<Equipamento> equipamentos) {
    this.equipamentos = equipamentos;
    notifyDataSetChanged();
}

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

Then check the size from the Activity:

adapter.getCount();

Upvotes: 0

Daniel Santos
Daniel Santos

Reputation: 85

GUYS, I've noticed that if I use:

                    equipamentos.clear(); //Clear List
                    for(Equipamento equipamento : equipamentoBox.getAll()){
                        equipamentos.add(equipamento); //Populate List
                    }
                    adapter = null;
                    adapter = new EquipamentoAdapter((Activity) Home.this, equipamentos);
                    listEquipamentos.setAdapter(adapter);
                    adapter.notifyDataSetChanged();

Its gonna work. But this seems VERY wrong in terms of performance. My application is small but I dont want to make bad practices.

Upvotes: 0

Gast&#243;n Saill&#233;n
Gast&#243;n Saill&#233;n

Reputation: 13129

One thing that you can do is reinflaiting the adapter, try this

public void refreshData(){
    this.equipamentos.clear();
    for(Equipamento equipamento : equipamentoBox.getAll()){
        this.equipamentos.add(equipamento);
    }

    EquipamentoAdapter adapter;adapter = new EquipamentoAdapter(this, equipamentos);
    listEquipamentos.setAdapter(adapter);
}

Upvotes: 0

Related Questions