Hot questions for Using Android EditText in arraylist

Question:

I know there are similar questions like this and I've been following a lot of code posted on here to get to this point, but none of them work to my adapter. I've also not used ViewHolders like many other people do as I do not really understand what they are for.

In my adapter class I wanted editing an editText to change its corresponding value in my ArrayList of event objects. However now changing one's event EditText field changes them all, even though I use mobileArrayList.get(position).

public class CustomAdapter extends ArrayAdapter {

ArrayList<Event> mobileArrayList;


public CustomAdapter (Context context, ArrayList<Event> events){
    super(context, 0, events);
    this.mobileArrayList = events;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent){
    Event event = mobileArrayList.get(position);
    //ViewHolder holder;
    if(convertView == null){
        //holder = new ViewHolder();
       // holder.caption = (EditText) convertView.findViewById(R.id.events);
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.listview_row, parent, false);
    } else {
        //holder = (ViewHolder) convertView.getTag();
    }


    EditText events = (EditText) convertView.findViewById(R.id.events);
    EditText start = (EditText) convertView.findViewById(R.id.start);
    EditText end = (EditText) convertView.findViewById(R.id.end);
    TextView day = (TextView) convertView.findViewById(R.id.day);

    events.setText(event.getSummary());
    start.setText("Start Date: " +event.getDateStart());
    end.setText("End Date: " + event.getDateEnd());
    day.setText(event.getDayOfTheWeek());

    /*holder.caption.setId(position);

    holder.caption.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus){
                final int position = v.getId();
                final EditText events = (EditText) v;
                mobileArrayList.get(position).setSummary(events.getText().toString());

            }
        }
    });*/

    events.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            String edit = s.toString();
            mobileArrayList.get(position).setSummary(edit);
        }
    });

    return convertView;
}

class ViewHolder{
    EditText caption;
}

}

I should also note once I get this working for the events EditText field I will also be doing the same for the other two. Thank you

EDIT: If I try to use this with ViewHolders instead, it throws an NPE when I try to assign the first holder.events = (EditText) convertView.findViewById(R.id.events). Here is the code using ViewHolders:

public class CustomAdapter extends ArrayAdapter {

ArrayList<Event> mobileArrayList;


public CustomAdapter (Context context, ArrayList<Event> events){
    super(context, 0, events);
    this.mobileArrayList = events;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent){
    Event event = mobileArrayList.get(position);
    ViewHolder holder;
    if(convertView == null){
        holder = new ViewHolder();
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.listview_row, parent, false);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }


    /*EditText events = (EditText) convertView.findViewById(R.id.events);
    EditText start = (EditText) convertView.findViewById(R.id.start);
    EditText end = (EditText) convertView.findViewById(R.id.end);
    TextView day = (TextView) convertView.findViewById(R.id.day);
    */

    holder.events = (EditText) convertView.findViewById(R.id.events);
    holder.start = (EditText) convertView.findViewById(R.id.start);
    holder.end = (EditText) convertView.findViewById(R.id.end);
    holder.day = (TextView) convertView.findViewById(R.id.day);

    holder.events.setText(event.getSummary());
    holder.start.setText("Start Date: " +event.getDateStart());
    holder.end.setText("End Date: " + event.getDateEnd());
    holder.day.setText(event.getDayOfTheWeek());

    /*holder.caption.setId(position);

    holder.caption.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus){
                final int position = v.getId();
                final EditText events = (EditText) v;
                mobileArrayList.get(position).setSummary(events.getText().toString());

            }
        }
    });*/

    holder.events.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            String edit = s.toString();
            mobileArrayList.get(position).setSummary(edit);
        }
    });

    return convertView;
}

class ViewHolder{
    EditText events;
    EditText start;
    EditText end;
    TextView day;
}

}


Answer:

try removing if(convertView == null) condition.

Question:

Hello this is the Java code that I want to rebuilt in Android but I'm having some problems. The java code:

package pickrandom;

import static java.lang.System.in;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.Random;

public class Pickrandom {
    static Random randomGenerator;

    static Scanner userInput = new Scanner(System.in);
    static List<String> strings = new ArrayList<String>();

    private static void displayList() {
        System.out.println(strings);
    }

    public static void main(String[] args) {
        // TODO code application logic here

        System.out.println("Please enter your strings:");
        String names;
        String item;
        while (true){
            names = userInput.next();
            if(names.equalsIgnoreCase("quit"))
                break;
            else
                strings.add(names);
        }
        displayList();

        randomGenerator = new Random();

        int index = randomGenerator.nextInt(strings.size());
        item=strings.get(index);

        System.out.println("Picked name is: " + item);
    }

}

And this is the output:

Please enter your strings: 
cafe 
bar 
cinema 
quit 
[cafe, bar, cinema] 
Picked name is: cafe

I want to write the similar code in my Android program. I want to write some names to my edittext line by line and choose one name randomly.

This is my XML:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="3dp"
    android:text="Enter all names in the field below, each on a separate line:"
    android:textColor="#000000"
    android:textSize="21sp"
    android:textStyle="bold"
    android:layout_marginTop="20dp"
    android:layout_marginBottom="20dp"/>
<EditText
    android:id="@+id/itemList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
<Button
    android:id="@+id/picker"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="PICK ONE"
    android:layout_weight="0"/>
<TextView
    android:id="@+id/result"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="3dp"
    android:text=""
    android:textColor="#000000"
    android:textSize="21sp"
    android:textStyle="bold"
    android:layout_marginTop="20dp"
    android:layout_marginBottom="20dp"/>

And my mainactivity:

public class MainActivity extends AppCompatActivity {

    static Random randomGenerator;
    static Scanner userInput = new Scanner(System.in);
    static List<String> strings = new ArrayList<String>();

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

        Button btn = (Button) findViewById(R.id.picker);

        final EditText itemList = (EditText) findViewById(R.id.itemList);
        final TextView myTextView = (TextView)findViewById(R.id.result);

        btn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {

                String items = itemList.getText().toString();

                String pickedItem;
                while (userInput.hasNextLine()){
                    strings.add(items);
                }
                randomGenerator = new Random();
                int index = randomGenerator.nextInt(strings.size());
                pickedItem=strings.get(index);

                myTextView.setText("Result: \n" + pickedItem);
            }
        });
    }
}

As I mentioned in the title I think I'm having problems about reading lines from an EditText and adding strings to the ArrayList. Thanks in advance for your help


Answer:

You should not use a Scanner anymore.

Once you get your String from your EditText, you should split it to obtain every line. Then add all substring to your List.

btn.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v) {

        String items = itemList.getText().toString();
        String[] subStrings = items.split("\n"); //split your String at every new line
        String pickedItem;
        strings.clear();
        for(String s : subStrings){ //run through all substrings to add them to the list
            strings.add(s);
        }
        randomGenerator = new Random();
        int index = randomGenerator.nextInt(strings.size());
        pickedItem=strings.get(index);

        myTextView.setText("Result: \n" + pickedItem);
    }
});

Question:

I am a true beginner to programming, so forgive me.

I have a String Array filled with a set of quotes that I have a method randomly picking one to display on the screen. This all works perfectly, I'd like to take the next step now. I would like to have the ability to add text to this array that a user inputs on an Activity that I have created. I understand that Arrays are Immutable, but I am failing to figure out how to create an ArrayList, pre-fill it with my 50ish quotes and then have the ability to add more through the app later.

Here is the code I currently have...

public class FactBook {
public String[] mFacts = {
            "Quote 1.",
            "Quote 2.", };

public String getFact() {

    String fact = "";
    Random randomGenerator = new Random();
    int randomNumber = randomGenerator.nextInt(mFacts.length);
    fact = mFacts[randomNumber];

    return fact;

    }

Answer:

References

ArrayList

Arrays

import java.util.ArrayList;
import java.util.Arrays;

public class FactBook {
    // Public data members are not recommended.
    // Make it at least protected and arrange controlled access to it
    // by specific methods
    public ArrayList<String> mFacts = 
       new ArrayList<String>(
                Arrays.asList("Quote 1.", "Quote 2.")
       )
    };

    public String getFact() {

        String fact = "";
        // Do you need to create a new Random every time?
        // Perhaps creating it only once and storing it in a static
        // (class wide) data member will be just as good: create it once,
        // reuse it later.
        Random randomGenerator = new Random();
        int randomNumber = randomGenerator.nextInt(mFacts.size());
        fact = mFacts.get(randomNumber);

        return fact;

    }

    // how to add
    public void add(String newQuip) {
        // Don't accept null or "all-white character" quotes
        if(null!=newQuip && newQuip.trim().length()>0) {
            this.mFacts.add(newQuip);
        }
    }
}

Question:

I have two classes that hold a bunch of data that the user inputs and specifies.

Class A has several parameters, and one of it's parameters is it gets assigned an instance of class B.

Now, both class A and B's values are able to be edited at any moment in Android by clicking on the object's reference inside of a ListView, via a custom built dialog that appears with editable forms.

Now when I am constructing class A, a dialog box pops up and asks me to fill out a name string, a int color and assign an instance of class from a Spinner B that was created and stored in an ArrayList.

My problem lies in that if I click on class B and change one of it's parameters; for instance it's string name or string phoneNum; I need to be able to update any instances of class A that use that edited instance of class B with the new class that is changed.

I guess I am confused on what a good way is to check and see if class B is being used by any of class A...


Answer:

The easiest way is probably to add a unique identifier to class B so that you can check which objects of class A have objects of B that you care about. For example:

public class B {

  private int id;

  private int getId() {
     return id;
  }
}

You should set the value of "id" in its constructor in a way that each instance of B would have a unique id. Then in your list of A's, you could just do this:

for (A a : listOfAs) {
  if (a.getB().getId() == theId) {
    // Do something to "a"
  }
}

where "theId" is the ID of B that you're currently modifying.

Question:

I'm trying to add EditText values to an ArrayList and display to a TextView, but I keep getting 'null' in the TV. I've tried several things, even looked at code from other projects where this is working... I don't know what is wrong...

package com.wizardpower.tester;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

String proContainer;
EditText etInput;
TextView tvOutput;
Button bButton;


List <String> proStrings = new ArrayList<>();

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

    for (int i = 0; i < proStrings.size(); i++){
        proContainer = proStrings.get(i);
    }

    bButton = (Button) findViewById(R.id.bButton);
    tvOutput = (TextView) findViewById(R.id.tvOutputTxt);
    etInput = (EditText) findViewById(R.id.etInput);
    bButton.setOnClickListener(this);

}

@Override
public void onClick(View v) {
    switch(v.getId()){
        case R.id.bButton:
            proStrings.add(etInput.getText().toString());
            tvOutput.setText(String.valueOf(proContainer));
            break;

    }
  }
}

Here is the XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:id="@+id/MainActivity">

<TextView android:text="OutputText" android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/tvOutputTxt"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="40dp" />

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/etInput"
    android:layout_below="@+id/textView"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="100dp"
    android:hint="add your text here" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Enter"
    android:id="@+id/bButton"
    android:layout_below="@+id/etInput"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="105dp" />


Answer:

This is what you should do:

StringBuilder proContainer;
List <String> proStrings = new ArrayList<>();

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



    bButton = (Button) findViewById(R.id.bButton);
    tvOutput = (TextView) findViewById(R.id.tvOutputTxt);
    etInput = (EditText) findViewById(R.id.etInput);
proContainer=new StringBuilder();
    bButton.setOnClickListener(this);

}

@Override
public void onClick(View v) {
    switch(v.getId()){
        case R.id.bButton:
            proStrings.add(etInput.getText().toString());
         for (int i = 0; i < proStrings.size(); i++){
           proContainer.append(proStrings.get(i));
         }
            tvOutput.setText(proContainer.toString());
            break;

    }
  }

Question:

I have 4 editText, and I want to store all the values in String arrayList. I have declared my arrayList globally. I can get the correct size of my arrayList, but I can't get any String value. Here's my code:

editText.setOnEditorActionListener(new TextView.OnEditorActionListener()
{
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
    {
        if(actionId == EditorInfo.IME_ACTION_DONE)
        {
            //get the user name
            String player1 = editText.getText().toString();
            playerName.add(player1);
        }
        return false;
    }
});
editText1.setOnEditorActionListener(new TextView.OnEditorActionListener()
{
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
    {
        if(actionId == EditorInfo.IME_ACTION_DONE)
        {
            //get the user name
            playerName.add(editText.getText().toString());
        }
        return false;
    }
});
editText2.setOnEditorActionListener(new TextView.OnEditorActionListener()
{
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
    {
        if(actionId == EditorInfo.IME_ACTION_DONE)
        {
            //get the user name
            playerName.add(editText.getText().toString());
        }
        return false;
    }
});
editText3.setOnEditorActionListener(new TextView.OnEditorActionListener()
{
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
    {
        if(actionId == EditorInfo.IME_ACTION_DONE)
        {
            //get the user name
            playerName.add(editText.getText().toString());
        }
        return false;
    }
});

Answer:

First, correct the listener, you use the same editText everywhere when you get the text editText.getText().toString().

Note : You could update this to use 1 instance of listener but that a different question.

To read a List, use List.get(int) or iterate it like

for(int i = 0; i < list.size(); ++i){
    String s = list.get(i);
    ...
}

or

for(String s : list){
    ...
}

Now, did you need to use a listener, or could you just get the value when you need it ? That your project but that's an idea. Because did you want to stack the value if you input a value twice in the same EditText?