I wrote a simple program that will display an ArrayList and the user can select an item and delete it with a button.
If the user does not select an item but continues to hit the delete button, they will remove the first item on the ArrayList. How do I prevent this from happening? The delete button should only run when an item is selected, so I need to find a way to check for that
int positionID;
ListView listview;
ArrayList<String> valuesArray = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (ListView) findViewById(R.id.listview);
valuesArray.add("a");
valuesArray.add("b");
valuesArray.add("c");
valuesArray.add("d");
valuesArray.add("e");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(),
android.R.layout.simple_list_item_1, valuesArray);
listview.setAdapter(adapter);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
positionID = (int) id;
}
});
}
public void onClickDelete(View v) {
//need to check if an item is selected. if so, run code below
valuesArray.remove(positionID);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, valuesArray);
listview.setAdapter(adapter);
}
Based on the code you've provided, this is likely happening because the default initialized value for positionID is set to 0. To fix this, you could initialize int positionID = -1 and then in your onClickDelete method, do a check to make sure the positionID is not invalid. Like this:
public void onClickDelete(View v) {
if (positionID < 0) return;
// continue your code here
}
By the way, a few other things you should fix. You should actually interact with adapter directly, so instead of valuesArray.remove(positionID) you should do adapter.remove(positionID). This will automatically update the adapter and refresh the ListView for you so you can get rid of the last two lines of your onClickDelete method.
You can just make valuesArray a local variable in your onCreate method, unless you plan on manipulating it directly elsewhere in your code. If you choose to do that, you can call adapter.notifyDataSetChanged() to make the adapter refresh your ListView.
Related
I have a ListView that displays an ArrayList that is dynamically created using an adapter. However, certain elements of each list item view are calculated based on previous item values. I am using Intents to open another activity where the user can edit a selected list item, and the updates are passed back to the main activity. In the main activity I've placed the getIntent, and the associated setters, after the ArrayList is generated and before the adapter. When the main activity is first created the adapter correctly calculates all list view items. But when the user accepts updates in the edit activity and returns to the main activity, only the selected list item is updated. Having the entire list cycle through and update would be fine (it will never be a very long list), but I'm a little surprised that only the selected list item is getting updated. I expected that either the adapter would run as it does when the activity is first created and all items would get updated, or that it wouldn't run at all and none would get updated.
public class MainActivity extends AppCompatActivity {
private final Context thisContext = MainActivity.this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView planListView = findViewById(R.id.plan_listview);
final ArrayList<ItemProfile> planSteps = BuildPlan();
if(getIntent().getExtras() != null)
{
int stepNumber = getIntent().getIntExtra("stepNumber", 0);
ItemProfile thisStep = (ItemProfile) getIntent().getSerializableExtra("itemProfile");
planSteps.get(stepNumber-1).setDepth(thisStep.getDepth());
planSteps.get(stepNumber-1).setTime(thisStep.getTime());
planSteps.get(stepNumber-1).setInterval(thisStep.getInterval());
}
ItemsListAdapter planAdapter = new ItemsListAdapter(this, planSteps);
planListView.setAdapter(planAdapter);
planListView.setOnItemClickListener(
new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int pos, long l)
{
int index = pos-1;
Intent i = new Intent(thisContext, EditItemActivity.class);
i.putExtra("stepNumber", pos);
i.putExtra("stepProfile", planSteps.get(index));
if (index > 0)
{
i.putExtra("groupStart", planSteps.get(index-1).getGroupEnd());
}
startActivity(i);
}
}
);
}
}
Update... I've added the mainActivity code. It creates an ArrayList plan (I'm using a BuildPlan method to populate a dummy plan while I'm developing) then checks for an intent that is returning an updated plan step. If an intent exists the specified step is updated in the plan. The list adapter is then created and set. Finally the clickListener is created and set.
I've done something relatively similar but I used dynamic spinners and listviews from a database.
Here is the code. Basically you invalidate the list view, reset the data and call notifyDataSetChanged() on the adapter.
public ListView lv;
Spinner suburbSpinner;
ArrayAdapter<String> suburbAdapter;
ArrayList<String> suburbs = new ArrayList<>();
ArrayList<Resource> resources = new ArrayList<>();
ArrayAdapter<Resource> arrayAdapter;
public void updateList(String type, String suburb, String businessType, int suburbPos) {
DatabaseHelper db = new DatabaseHelper(this, "fairCanberraDB", null, 1);
lv = findViewById(R.id.list);
// Reset suburb spinner, get new list view resources.
lv.invalidateViews();
resources = db.resourceQuery(type, suburb, businessType);
System.out.println("resource: " + resources);
ArrayList<Resource> suburbQuery = db.resourceQuery(type, "All", businessType);
Spinner suburbSpinner = findViewById(R.id.suburbSpinner);
suburbs.clear();
suburbs.add("All");
for (int x = 0; x < suburbQuery.size(); x++) {
if (suburbs.contains(suburbQuery.get(x).getSuburb())) {
continue;
} else {
suburbs.add(suburbQuery.get(x).getSuburb());
}
}
db.close();
suburbAdapter.notifyDataSetChanged();
arrayAdapter.notifyDataSetChanged();
ArrayAdapter<Resource> arrayAdapter = new ArrayAdapter<Resource>(
this,
android.R.layout.simple_list_item_1,
resources);
lv.setAdapter(arrayAdapter);
if(suburbPos < suburbSpinner.getCount())
{ suburbSpinner.setSelection(suburbPos);}
setSpinnerListener(suburbSpinner);
}
// Register listener for a spinner
public void setSpinnerListener(Spinner spinner)
{
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
Spinner typeSpinner = (Spinner) findViewById(R.id.typeSpinner);
Spinner businessTypeSpinner = (Spinner) findViewById(R.id.businessTypeSpinner);
Spinner suburbSpinner = (Spinner) findViewById(R.id.suburbSpinner);
String businessType = businessTypeSpinner.getSelectedItem().toString();
if(businessType.contains("Private"))
{
businessType = "private user";
}
updateList(typeSpinner.getSelectedItem().toString(), suburbSpinner.getSelectedItem().toString(),
businessType, suburbSpinner.getSelectedItemPosition());
}
How can I get the item's text from an adapter's listview?
In my adapter I have this code:
final ArrayList> userList = controller.getAllUsers();
if (userList.size() != 0) {
//Set the User Array list in ListView
ListAdapter adapter = new SimpleAdapter(PoliceSmsRegisterReceiver.this, userList, R.layout.view_user_entry_register,
new String[]{"userId", "sender", "fullname", "homeaddress", "emailaddress", "phonenumber", "password", "deviceid"},
new int[]{R.id.userId, R.id.viewSender, R.id.viewFName, R.id.viewHAddress, R.id.viewEAddress, R.id.viewPNumber, R.id.viewPassword, R.id.viewA_ID});
ListView myList = (ListView) findViewById(android.R.id.list);
myList.setAdapter(adapter);
(p.s ; controller is my sqlite db)
then this is my onclick:
myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
}
});
What I want to know is how I can toast the specific string in the adapter when clicking the specific item in the list. Example, I want to toast the viewSender.
You can use AdapterView and position provided by setOnItemClickListener to get any information about clicked item :
Toast.maketext(context,(ModelClass)parent.getItemAtPosition(position).getSpecificText(),Toast.LENGTH_SHORT).show();
You can use int position like this.
Toast.maketext(context,String.valueof(position),Toast.LENGTH_SHORT).show();
An OnItemClickListener handles clicking a list item.
You have to use a custom adapter in which you grab hold of all the Views in the row in getView() and set onClickListeners on them there.
I search a lot of similar question...all of them say I must use something like this code:
arrayAdapter.notifyDataSetChanged();
after this code: bookmarks.remove(pos);
but you can see...in BookMarkActivity class do not use arrayAdapter
public class BookMarkActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.message);
// Reading all contacts
final ArrayList<BookMark> bookmarks = (ArrayList<BookMark>) db.getAllBookMarks();
BuildingAdapter adapter = new BuildingAdapter(context);
// ADDED
final ListView lv = (ListView) findViewById(R.id.list_view);
lv.setAdapter(new BookmarkAdapter(this, bookmarks));
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int pos, long id) {
bookmarks.remove(pos);
return true;
}
});
}
}
I am new in android...but I try change code with this:
private ArrayAdapter<BookMark> arrayAdapter;
arrayAdapter = new BookmarkAdapter(this, bookmarks);
but no success! the listview do not be refresh after delete one item!
ListView displays some data stored in an ArrayList.
When element remove or add in ArrayList, you have to tell the list that the source of the data had changed to show the new data.
So, that is where notifyDatasetChanged() comes in. It tells the ListView that the data has been modified so please reflect the changed data.
final BookmarkAdapter adapter = new BookmarkAdapter(this, bookmarks);
lv.setAdapter(adapter);
and after remove element use below line.
adapter.notifyDataSetChanged();
hope it helps.
Just add two lines on the button/imageView click listeners.
delete.setOnClickListener {
list.removeAt(pos)
notifyItemRemoved(pos)
}
I am having a problem with ListViews and ArrayLists.
I have an ArrayList of items. Each item has info such as ID, Title, Price etc. I also have another ArrayList of allocations. These allocations contain an "ItemId" variable - so I plan to link this to item. (Without the use of a database.)
This is how I think I will do it. First of all I will convert my ArrayList of items into a ListView using AndroidStudio. When the user clicks on a specific item on this ListView, I will run an if statement (e.g if the Id of the selected item is 2, display the allocation with that itemId)
However there is a problem with this. I can't check the Id in this if statement because my ArrayList has already been converted to a ListView, which I can not search for specific data. Can anyone help me?
Here is the code I have at the moment:
public class ViewItems extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_items_layout);
ListAdapter itemAdapter = new ArrayAdapter<Item>(this, android.R.layout.simple_list_item_1, Item.itemArrayList);
ListView itemListView = (ListView) findViewById(R.id.itemListView);
itemListView.setAdapter(itemAdapter);
itemListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String itemPicked = ????;
IF STATEMENT GOES HERE;
}});
}
}
You don't 'convert' your ArrayList into a ListView. The ListView merely uses the ArrayList to show your items - the ArrayList is still valid.
More precise, you add your items to the ArrayAdapter, which uses your exact ArrayList. You can use:
itemAdapter.getItem(i);
Complete example:
final ArrayAdapter<Item> itemAdapter = new ArrayAdapter<Item>(this, android.R.layout.simple_list_item_1, Item.itemArrayList);
ListView itemListView = (ListView) findViewById(R.id.itemListView);
itemListView.setAdapter(itemAdapter);
itemListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Item itemPicked = itemAdapter.getItem(i);
IF STATEMENT GOES HERE;
}
});
Note that since you're putting instances of Item in your ArrayList, itemAdapter.getItem(i) will return an Item, not a String.
Use getItem of your ArrayAdapter
itemAdapter.getItem (i);
I'm trying to set a ListView and I was able to do it using a simple String[] Array as you can see in the code.
Later on, I commented out the Array and used a List
My problem starts when I want to use the List (since I need to manipulate the contents) and a simple Array can't be dynamically changed.
When I use the List I get a NullPointerException when I create the ArrayAdapter and I don't know why.
I read in the documentation of the ArrayAdapter that it is overloaded with 6 different constructors and one of them is
ArrayAdapter(Context context, int resource, List objects)
Why am I getting the NullPointerException?
What should I do to make it work with a List instead of an Array?
Thanks in advance!
public class MainActivity extends Activity implements OnItemClickListener {
ListView l;
// String[] days = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
List<String> days;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
days.add(0, "Sunday");
days.add(1, "Monday");
days.add(2, "Tuesday");
days.add(3, "Wednesday");
days.add(4, "Thursday");
days.add(5, "Friday");
days.add(6, "Saturday");
l = (ListView) findViewById(R.id.listView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, days);
l.setAdapter(adapter);
l.setOnItemClickListener(this);
}
#Override
public void onItemClick(
AdapterView<?> adapterView, // ListView that was clicked
View view, // Reference to the row that was clicked (each row is a TextView)
int i, // position
long l) { // id of the TextView that was clicked
Toast.makeText(this, days.get(i) + " " + i, Toast.LENGTH_LONG).show();
}
}
You forgot to initialise the days field with anything, so it remains null when you call the add method. Before the days.add(0, "Sunday"); line, add this:
days = new ArrayList<String>();
Also, take out the index numbers. Just use days.add("Sunday"); days.add("Monday");, and so on.
You need to create days:
List<String> days = new ArrayList<String>();
for example.