Nicola
Nicola

Reputation: 331

Is it possible to pass only String to a custom listview adapter?

I am passing through a while loop which has different Strings for my adapter. But it doesn't show anything, however if I pass an array it works. I don't know if I can pass only a String and if the return of the overridden methods are correct.

public class ReportAdapter extends BaseAdapter {

private Context context;
private String debtor;
private String receiver;
private BigDecimal difference;
private String groupName;
LayoutInflater inflater;

public ReportAdapter(Context applicationContext, String debtor, String receiver, BigDecimal difference, String groupName) {
    this.context = applicationContext;
    this.debtor = debtor;
    this.receiver = receiver;
    this.difference = difference;
    this.groupName = groupName;
    inflater = LayoutInflater.from(applicationContext);

}


@Override
public int getCount() {
    return 0;
}

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

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

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    DecimalFormat df = new DecimalFormat("##.00");
    SharedPreferences sharedPrefs = context.getSharedPreferences("sharedPrefs", Context.MODE_PRIVATE);
    final SharedPreferences.Editor editor = sharedPrefs.edit();
    convertView = inflater.inflate(R.layout.report_list_view, null);
    TextView debtor = convertView.findViewById(R.id.debtor_tv);
    TextView receiver = convertView.findViewById(R.id.receiver);
    TextView difference = convertView.findViewById(R.id.difference_tv);
    final CardView paidCard = convertView.findViewById(R.id.paid_cardview);
    final Switch paidSwitch = convertView.findViewById(R.id.paid_switch);


    debtor.setText(debtor.toString());

    receiver.setText(receiver.toString());

    difference.setText(String.valueOf(df.format(difference) + "€"));

    paidSwitch.setChecked(sharedPrefs.getBoolean(groupName + "_checkValue" + position, false));
    if (paidSwitch.isChecked()) {
        // Set green background
        paidCard.setCardBackgroundColor(Color.parseColor("#FF2E7D32"));
    }
    paidSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                // Set green background
                paidCard.setCardBackgroundColor(Color.parseColor("#FF2E7D32"));
                editor.putBoolean(groupName + "_checkValue" + position, isChecked);
                editor.commit();

            } else {
                // Set red background
                paidCard.setCardBackgroundColor(Color.parseColor("#FFB71C1F"));
                editor.putBoolean(groupName + "_checkValue" + position, isChecked);
                editor.commit();

            }

        }
    });
    return convertView;
}

The listview doesn't appear. Could it be that the constructor accepts only Array type? Or I can pass a String? The getCount() and the getItem() methods, have to return 0? Because with an ArrayList I return the arraylist.get(position), but with a String, what should I return?

Upvotes: 0

Views: 76

Answers (1)

Barns
Barns

Reputation: 4848

Certainly you can pass String values to your ListView. My question would be: Why use a ListView for a single entry? A ListView generates a lot of overhead.

Why the ListView is not showing any values is because the method getCount()dictates how many rows are displayed in your list.

A better solution would be to create a custom class--maybe Transactions that contains getters and setters for debtor and receiver. Add a new Transactions to an ArrayList for each row to be displayed in the ListView...even if it is only one row.


Possible solution::

public class MyListAdapter extends ArrayAdapter<Transaction> {

    private static final String TAG = MyListAdapter.class.getSimpleName();


    public MyListAdapter(Context context, ArrayList<Transaction> transactionList) {
        super(context, 0, transactionList);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent){

        Transaction transactionData = getItem(position);

        if(convertView == null){
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_layout_2, parent, false);
        }

        TextView textView1 = (TextView) convertView.findViewById(R.id.textView1);
        TextView textView2 = (TextView) convertView.findViewById(R.id.textView2);


        String debtor = transactionData.getDebtor();
        String receiver = transactionData.getReceiver();
        textView1.setText(debtor);
        textView2.setText(receiver);

        return convertView;
    }
}

The custom Transaction class could look like this:

public class Transaction {

    private String debtor = "";
    private String receiver = "";

    public Transaction(){
    }
    public Transaction(String debtor, String receiver){
        this.debtor = debtor;
        this.receiver = receiver;
    }

    public void setDebtor(String debtor){ this.debtor = debtor; }
    public void setReceiver(String receiver){ this.receiver = receiver; }

    public String getDebtor(){ return this.debtor; }
    public String getReceiver() { return this.receiver; }
}

Now you can simply populate the list:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // There would of course be a better way to populate the data!!
    ArrayList<> transactionList = new ArrayList<>();
    transactionList.add(new Transaction("Mike","Bob"));


    MyListAdapter theAdapter = new MyListAdapter(this, arrayDriverListData);

    ListView transaction_list = (ListView) findViewById(R.id.transaction_list);

    transaction_list.setAdapter(theAdapter);
}

NOTE:
I typed this in a standard TextEditor (no auto-correct) ... so there might be a few errors.

Upvotes: 2

Related Questions