The problem: I want to remove a item from my listview using a button in another activity.
I have tried several kinds of code, but it just doesn't seem to work.
Right know I use serializable to bundle the object to the other activity.
But I don't know how to remove it, from the other activity.
Can anybody help me with that?
Can I use the button from the second activity, in the first activity to delete the item from the listview?
Class A where I got my ListView
public class ListActivity extends Activity {
ListView list;
Button exit;
SimpleAdapter adapter;
final List<Map<String, String>> data = new ArrayList<Map<String, String>>();
#Override``
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
list = (ListView) findViewById(R.id.list);
exit = (Button) findViewById(R.id.btnExit);
// Registration numbers
final String[] title = new String[] { "XMT 123", "KLE 456", "CKL 789",
"MRP 012", "DSV 345" };
// Name of the truck drivers
final String[] subtitle = new String[] { "Peter Lund", "Hans Larsson",
"Erik Petersson", "Bjørn Lundal", "Lars Svensson" };
for (int i = 0; i < title.length; i++) {
Map<String, String> datalist = new HashMap<String, String>();
datalist.put("title", title[i]);
datalist.put("subtitle", subtitle[i]);
data.add(datalist);
}
// getDataInList();
adapter = new SimpleAdapter(this, data,
android.R.layout.simple_list_item_2, new String[] { "title",
"subtitle" }, new int[] { android.R.id.text1,
android.R.id.text2 });
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
Intent intent = new Intent(ListActivity.this,
InformationActivity.class);
intent.putExtra("updateReg", title[position].toString());
intent.putExtra("updateName", subtitle[position].toString());
}
});
exit.setOnClickListener(new OnClickListener() {
// Closes the application
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
Class B where I got my accept button.
When I click accept, the item from the listview in Class A should be removed.
public class InformationActivity extends Activity {
TextView name;
TextView reg;
TextView product;
TextView productNo;
Button accept;
Button edit;
Button exit;
AlertDialog dialog;
ListView list;
String result;
EditText search;
int requestCode = 1;
SimpleAdapter adapter;
Context context = InformationActivity.this;
ArrayList<Materials> materialList = new ArrayList<Materials>();
// Materials
final static String[] material = new String[] { "Betong", "Grus", "Järn",
"Metall", "Grus fin", "Grus grov", "Sten" };
// Material numbers
final static String[] materialNo = new String[] { "123", "234", "345",
"456", "567", "789", "012" };
private void getDataInList() {
for (int i = 0; i < 7; i++) {
Materials mats = new Materials(result, result);
mats.setMaterialName(material[i]);
// mats.setMaterialNo(material[i]);
materialList.add(mats);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.information_activity);
name = (TextView) findViewById(R.id.name);
reg = (TextView) findViewById(R.id.reg);
product = (TextView) findViewById(R.id.product);
productNo = (TextView) findViewById(R.id.productNo);
accept = (Button) findViewById(R.id.btnAccept);
edit = (Button) findViewById(R.id.btnEdit);
list = (ListView) findViewById(R.id.list);
Bundle extras = getIntent().getExtras();
String selected_item = extras.getString("updateReg");
reg = (TextView) findViewById(R.id.reg);
reg.setText(selected_item);
Bundle extras1 = getIntent().getExtras();
String selected_item1 = extras1.getString("updateName");
name = (TextView) findViewById(R.id.name);
name.setText(selected_item1);
getDataInList();
edit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final AlertDialog.Builder popup = new AlertDialog.Builder(
InformationActivity.this);
popup.setTitle("Välj ny artikel");
// Search field
final EditText search = new EditText(context);
popup.setView(search);
search.setHint("Sök här...");
popup.setSingleChoiceItems(material, -1,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
materialList.get(which);
Toast.makeText(getApplicationContext(),
material[which], Toast.LENGTH_SHORT)
.show();
result = material[which];
}
});
// PositiveButton, updates the material info field.
popup.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
product.setText(result);
}
});
// NegativeButton, closes the pop-up.
popup.setNegativeButton("Avbryt",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
});
dialog = popup.create();
dialog.show();
}
});``
//Remove item
accept.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
You should not directly remove the item from the view, but from the data displayed in it.
For example if your ListView is displaying items from an ArrayList, just remove the item in the ArrayList from you Activity B, and call myAdapter.notifyDataSetChanged() when back in the Activity A, which contains the adapter.
You can remove items by accessing to the ArrayList or by overriding the remove() method if you have only access to the adapter (assuming your adapter extends ArrayAdapter).
Also, you may have to override usefull Adapter methods like getCount(), getView()...
Thanks to all.
I found another solution thanks to remove row from another activity
Class A
public class ListActivity extends Activity {
ListView list;
Button exit;
static List<ListItems> items = new ArrayList<ListItems>();
public static int deletePos;
static ListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
list = (ListView) findViewById(R.id.list);
exit = (Button) findViewById(R.id.btnExit);
// Registration numbers
final String[] title = new String[] { "XMT 123", "KLE 456", "CKL 789",
"MRP 012", "DSV 345" };
// Name of the truck drivers
final String[] subtitle = new String[] { "Peter Lund", "Hans Larsson",
"Erik Petersson", "Bjørn Lundal", "Lars Svensson" };
items = new ArrayList<ListItems>();
for (int i = 0; i < title.length; i++) {
ListItems s = new ListItems(title[i], subtitle[i]);
items.add(s);
}
adapter = new ListAdapter(this, android.R.layout.simple_list_item_2,
items);
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
Intent intent = new Intent(ListActivity.this,
InformationActivity.class);
intent.putExtra("updateReg", title[position].toString());
intent.putExtra("updateName", subtitle[position].toString());
deletePos = position;
adapter.notifyDataSetChanged();
startActivity(intent);
}
});
exit.setOnClickListener(new OnClickListener() {
// Closes the application
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
}
Class B
public class InformationActivity extends Activity {
TextView name;
TextView reg;
TextView product;
TextView productNo;
Button accept;
Button edit;
Button exit;
AlertDialog dialog;
ListView list;
String result;
EditText search;
Context context = InformationActivity.this;
ArrayList<Materials> materialList = new ArrayList<Materials>();
// Materials
final static String[] material = new String[] { "Betong", "Grus", "Järn",
"Metall", "Grus fin", "Grus grov", "Sten" };
// Material numbers
final static String[] materialNo = new String[] { "123", "234", "345",
"456", "567", "789", "012" };
private void getDataInList() {
for (int i = 0; i < 7; i++) {
Materials mats = new Materials(result, result);
mats.setMaterialName(material[i]);
// mats.setMaterialNo(material[i]);
materialList.add(mats);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.information_activity);
name = (TextView) findViewById(R.id.name);
reg = (TextView) findViewById(R.id.reg);
product = (TextView) findViewById(R.id.product);
productNo = (TextView) findViewById(R.id.productNo);
accept = (Button) findViewById(R.id.btnAccept);
edit = (Button) findViewById(R.id.btnEdit);
list = (ListView) findViewById(R.id.list);
Bundle extras = getIntent().getExtras();
String selected_item = extras.getString("updateReg");
reg = (TextView) findViewById(R.id.reg);
reg.setText(selected_item);
Bundle extras1 = getIntent().getExtras();
String selected_item1 = extras1.getString("updateName");
name = (TextView) findViewById(R.id.name);
name.setText(selected_item1);
getDataInList();
edit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final AlertDialog.Builder popup = new AlertDialog.Builder(
InformationActivity.this);
popup.setTitle("Välj ny artikel");
// Search field
final EditText search = new EditText(context);
popup.setView(search);
search.setHint("Sök här...");
popup.setSingleChoiceItems(material, -1,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
materialList.get(which);
Toast.makeText(getApplicationContext(),
material[which], Toast.LENGTH_SHORT)
.show();
result = material[which];
}
});
// PositiveButton, updates the material info field.
popup.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
product.setText(result);
}
});
// NegativeButton, closes the pop-up.
popup.setNegativeButton("Avbryt",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
});
dialog = popup.create();
dialog.show();
}
});
// Remove item
accept.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int deletePos = ListActivity.deletePos;
ListActivity.items.remove(deletePos);
ListActivity.adapter.notifyDataSetChanged();
finish();
}
});
}
}
Related
I am making android app for college. App is about fitness(tracking kcal,workouts...). i have stuck on part where i want to notifyDatasetChange for my adapter. On my Activity i have 2 list views(first is showing exercises and second is showing selected exercises for todays workout). I made easily first ListView to update when user "create" new type of exercise for itself because Arraylist and called from current activity ,but for second ListView i made Dialog in its adapter class and i want on closing that dialog to update ListView. Here is my code and classes:
public class MyWorkoutActivity extends AppCompatActivity {
ListView lv;
ListView lvsess;
Button create;
#Override
public void onBackPressed(){
finish();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_workout);
create=(Button) findViewById(R.id.btn_addexercise);
WorkoutDay workoutDay = SugarRecord.findById(WorkoutDay.class, (long) 1);
List<WorkoutDay> workoutDayArrayList = new ArrayList<>();
if(workoutDay.getWorkouts()!="") {
String[] workouts = workoutDay.getWorkouts().split(":");
String[] sets = workoutDay.getSets().split(":");
String[] reps = workoutDay.getReps().split(":");
String[] kgs = workoutDay.getKgs().split(":");
String[] duration = workoutDay.getDuration().split(":");
for (int i = 0; i < workouts.length; i++) {
workoutDayArrayList.add(new WorkoutDay(workouts[i],sets[i],reps[i],kgs[i],duration[i]));
}
}
final ArrayList<WorkoutDay> ddd = new ArrayList<>();
ddd.addAll(workoutDayArrayList);
List<Exercise> exerciseList = Exercise.listAll(Exercise.class);
final ArrayList<Exercise> exerciseArrayList= new ArrayList<>();
exerciseArrayList.addAll(exerciseList);
lv=(ListView) findViewById(R.id.lv_exercises);
lvsess=(ListView)findViewById(R.id.lv_currentsess);
final SessionAdapter sessionAdapter = new SessionAdapter(this,ddd);
final ExerciseAdapter exerciseAdapter= new ExerciseAdapter (this,exerciseArrayList);
lv.setAdapter(exerciseAdapter);
lvsess.setAdapter(sessionAdapter);
create.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
List<String> cathegories = new ArrayList<String>();
cathegories.add("Chest");
cathegories.add("Biceps");
cathegories.add("Triceps");
cathegories.add("Legs");
cathegories.add("Core");
cathegories.add("Abdomens");
cathegories.add("Cardio");
cathegories.add("Free style");
final Dialog addyourown= new Dialog(MyWorkoutActivity.this);
addyourown.setTitle("Add your exercise");
addyourown.setContentView(R.layout.addyourownex);
Button btn = (Button)addyourown.findViewById(R.id.btn_dialog_add);
final EditText et = (EditText)addyourown.findViewById(R.id.et_dialog_insertname);
final Spinner spinner = (Spinner)addyourown.findViewById(R.id.sp_cath);
ArrayAdapter<String> adapter ;
adapter = new ArrayAdapter<String>(getApplicationContext(),android.R.layout.simple_spinner_dropdown_item,cathegories);
spinner.setAdapter(adapter);
addyourown.show();
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(et.getText().toString().isEmpty()){
Toast.makeText(getApplicationContext(),"EMPTY INPUT",Toast.LENGTH_SHORT).show();
}else {
Exercise exercise = new Exercise(et.getText().toString(), spinner.getSelectedItem().toString());
exercise.save();
exerciseArrayList.add(exercise);
exerciseAdapter.notifyDataSetChanged();
addyourown.cancel();
}
}
});
}
});
}
and my adapter class with dialog
public class ExerciseAdapter extends ArrayAdapter<Exercise> {
public Dialog newDialog;
public ExerciseAdapter(#NonNull Context context, ArrayList<Exercise> exercises) {
super(context,0,exercises);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
final Exercise exercise = getItem(position);
if(convertView==null){
convertView= LayoutInflater.from(getContext()).inflate(R.layout.exercises_layout,parent,false);
}
TextView name = (TextView)convertView.findViewById(R.id.tv_exercise);
ImageButton ib= (ImageButton)convertView.findViewById(R.id.ib_plus);
name.setText(exercise.getName());
ib.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
newDialog = new Dialog(v.getRootView().getContext());
if(exercise.getCathegory().equals("Cardio")) {
newDialog.setContentView(R.layout.cardio_layout);
final EditText duration = (EditText)newDialog.findViewById(R.id.et_duration);
Button bt = (Button) newDialog.findViewById(R.id.btn_carconfirm);
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(duration.getText().toString().equals("")){
Toast.makeText(getContext(),"EMPTY INPUT",Toast.LENGTH_SHORT).show();
}else {
WorkoutDay workoutDay = SugarRecord.findById(WorkoutDay.class,(long)1);
workoutDay.extendCardio(exercise.getName(),duration.getText().toString());
workoutDay.save();
newDialog.cancel();
}
}
});
} else {
newDialog.setContentView(R.layout.instervalue_exercises);
final EditText sets = (EditText)newDialog.findViewById(R.id.et_series);
final EditText reps = (EditText)newDialog.findViewById(R.id.et_reps) ;
final EditText kgs = (EditText)newDialog.findViewById(R.id.et_kg);
Button bt = (Button) newDialog.findViewById(R.id.btn_confirm);
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(sets.getText().toString().equals("") || reps.getText().toString().equals("") || kgs.getText().toString().equals("")){
Toast.makeText(getContext(),"EMPTY INPUT",Toast.LENGTH_SHORT).show();
}else {
WorkoutDay workoutDay = SugarRecord.findById(WorkoutDay.class,(long)1);
workoutDay.extendExercise(exercise.getName(),sets.getText().toString(),reps.getText().toString(),kgs.getText().toString());
workoutDay.save();
newDialog.cancel();
}
}
});
}
newDialog.show();
}
});
return convertView;}
I want to programm a ChatApp with Firebase. Right now I am displaying the Users I chat with. But now I want them to be sorted by a Date String I am using:
For Example: 21-06-2017 17:20. It should be sorted from the latest Time to the earliest Time.
My Adapter:
public class ChatAdapter extends ArrayAdapter<String> {
private Activity context;
private List<Chats> chatsList = new ArrayList<>();
public ChatAdapter(Activity context, List<Chats> chatsList) {
super(context, R.layout.abc_main_chat_item);
this.context = context;
this.chatsList = chatsList;
}
#Override
public View getView(final int position, final View convertView, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View listViewItem = inflater.inflate(R.layout.abc_main_chat_item, null, true);
TextView tvusername = (TextView) listViewItem.findViewById(R.id.group_name);
TextView tvuid = (TextView) listViewItem.findViewById(R.id.useruid);
TextView tvlastmessage = (TextView) listViewItem.findViewById(R.id.latestMessage);
TextView tvlastmessagetime = (TextView) listViewItem.findViewById(R.id.latestMessageTime);
ImageView ivphoto = (ImageView) listViewItem.findViewById(R.id.profileImg);
tvusername.setText(chatsList.get(position).getUsername());
tvlastmessage.setText(chatsList.get(position).getLastMessage());
tvlastmessagetime.setText(chatsList.get(position).getLastMessageTime());
tvuid.setText(chatsList.get(position).getUseruid());
Picasso.with(getContext()).load(chatsList.get(position).getPhotoURL()).placeholder(R.drawable.ic_person_grey_round).into(ivphoto);
listViewItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(context, Chat_Room.class);
i.putExtra("room_name", chatsList.get(position).getUsername());
i.putExtra("room_uid", chatsList.get(position).getUseruid());
context.startActivity(i);
}
});
listViewItem.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.abcd_listview_alertdia_layout);
ArrayList<String> list_of_chats = new ArrayList<>();
final ArrayAdapter<String> arrayAdapter;
arrayAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, list_of_chats);
list_of_chats.add(0, "Chatverlauf mit "+ chatsList.get(position).getUsername()+" löschen?");
list_of_chats.add(1, "Profil von "+chatsList.get(position).getUsername()+" anschauen");
arrayAdapter.notifyDataSetChanged();
final ListView lv = (ListView) dialog.findViewById(R.id.lv);
lv.setAdapter(arrayAdapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, final int position2, long id) {
if (position2 == 0) {
dialog.dismiss();
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle("Chatverlauf mit "+chatsList.get(position).getUsername()+" löschen?")
.setMessage("Du kannst das Löschen nicht rückgängig machen. Bist du dir sicher?")
.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
FirebaseDatabase.getInstance().getReference().child("chats").child("userchats").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child(chatsList.get(position).getUseruid()).setValue(null);
FirebaseDatabase.getInstance().getReference().child("chats").child("users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("messages").child(chatsList.get(position).getUseruid()).setValue(null);
}
}).setCancelable(true)
.show();
lv.setAdapter(arrayAdapter);
arrayAdapter.notifyDataSetChanged();
}
if (position2 == 1) {
Intent intent = new Intent(context, ViewContact.class);
intent.putExtra("useruid", chatsList.get(position).getUseruid());
context.startActivity(intent);
}
}
});
dialog.show();
return true;
}
});
ivphoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.abcd_profile_pic_dialog_layout);
ImageView imageView = (ImageView) dialog.findViewById(R.id.alertImage);
TextView textView = (TextView)dialog.findViewById(R.id.alertdialogtv);
ImageView message = (ImageView)dialog.findViewById(R.id.alertMessage);
ImageView profile = (ImageView)dialog.findViewById(R.id.alertProfile);
profile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, ViewContact.class);
intent.putExtra("useruid", chatsList.get(position).getUseruid());
context.startActivity(intent);
dialog.dismiss();
}
});
message.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), Chat_Room.class);
intent.putExtra("room_name", chatsList.get(position).getUsername());
intent.putExtra("room_uid", chatsList.get(position).getUseruid());
context.startActivity(intent);
}
});
Picasso.with(getContext()).load(chatsList.get(position).getPhotoURL()).placeholder(R.drawable.ic_person_grey_round).into(imageView);
textView.setText(chatsList.get(position).getUsername());
dialog.setCancelable(true);
dialog.show();
}
});
return listViewItem;
}
This is how i got my ArrayLists:
`for(DataSnapshot snapshot : dataSnapshot.getChildren()){
username.add(snapshot.child("roomname").getValue().toString());
photoURL.add(snapshot.child("photoURL").getValue().toString());
lastmessage.add(snapshot.child("lastMessage").getValue().toString());
lastmessagetime.add(snapshot.child("lastMessageTime").getValue().toString());
useruid.add(snapshot.child("userUiD").getValue().toString());
}
ChatAdapter chatAdapter = new ChatAdapter(getActivity(), username, useruid, photoURL, lastmessage, lastmessagetime);
listView.setAdapter(chatAdapter);`
But how can I pass it as a List ??
How can I add them to the list?
Is it even possible to sort it?
I hope you Guys can help me :)
Thanks.
This is of course possible.
But first, your data structure looks weird and unpractical.
Your messages are passed in single arrays which makes it quite complicated:
ArrayList<String> username, ArrayList<String> useruid, ArrayList<String> photoURL, ArrayList<String> lastmessage, ArrayList<String> lastmessagetime
Better would be to have a list of Messageobjects, where a message object contains the single items, something like this:
public class Message {
String username;
String useruid;
String photoURL;
String message;
Date timestamp;
//...getter and setter
}
Even better would be to have a Message object just contain a userId, messageText and timeStamp. that's all you would need.
Then you could pass a List<Message> messages into your adapter.
To sort the message list you can implement the Comparable class where you can then sort the objects in a way you like.
public class Message implements Comparable<Message>{
String username;
String useruid;
String photoURL;
String message;
Date timestamp;
#Override
public int compareTo(#NonNull Message o) {
return this.timestamp.compareTo(o.timestamp)
}
}
If you have added Comparable to your Messageclass, you can use
Collections.sort(messages); to sort the list.
Just have a look at the java comparable, there are various examples. Also check out this stackoverflow answer.
edit: to answer your additional question:
in your case, when you are getting your elements you would do something like:
List<Message> messages = new ArrayList<Message>();
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
Message message = new Message();
message.setName(snapshot.child("roomname").getValue().toString());
…
//set all your properties and then add that object to the messages list
messages.add(message);
}
Collections.sort(messages); // sort the message list
ChatAdapter chatAdapter = new ChatAdapter(getActivity(), messages);
listView.setAdapter(chatAdapter);
I'm new in Android. I have the same problem as described here...I am trying to manage a simple list in an Android application. The contents of the list are maintained in a SQLite database. When the user selects and holds on a specific row, a context menu appears with a "Open/Delete" option. When they select "Delete", the row is deleted from the database, but the view does not refresh. When I back out of the application and get back in, the appropriate row has been removed. So, I know the row is deleted, it's just the ListView that doesn't refresh. The same with adding new item to the database. I searched solution, but not yet find. Appreciate any help.
Activity class:
public class ProjectsActivity extends Activity {
private RMProject rmProject = null;
private RMProjectDBHelper projectDBHelper = null;
ArrayAdapter<String> adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
rmProject = new RMProject();
projectDBHelper = new RMProjectDBHelper(this);
final ListView lv = (ListView) findViewById(R.id.list);
adapter = new ArrayAdapter<>(this, R.layout.list_item, getProjectNames());
adapter.notifyDataSetChanged();
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
AlertDialog.Builder builder = new AlertDialog.Builder(ProjectsActivity.this);
builder.setTitle("What to do with project?");
builder.setPositiveButton("Open", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ProjectsActivity.this, OpenProjectActivity.class);
//todo: send project information as parameter
startActivity(intent);
}
});
//**!!!Here I delete project item from database!!!**
builder.setNegativeButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String selected = ((TextView) view.findViewById(R.id.list_textView)).getText().toString();
int projId = projectDBHelper.findIdByName(selected);
projectDBHelper.deleteProject(projId);
Toast toast=Toast.makeText(getApplicationContext(), "Project "+selected+" deleted", Toast.LENGTH_SHORT);
toast.show();
//**call getProjectNames and notifydataSetChanged**
getProjectNames();
adapter.notifyDataSetChanged();
}
});
builder.show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_item) {
final Dialog dialog = new Dialog(ProjectsActivity.this);
dialog.setContentView(R.layout.add_proj);
dialog.setTitle("Введите название проекта:");
dialog.setCancelable(false);
Button okBtn = (Button) dialog.findViewById(R.id.btn_create_proj);
Button cancelBtn = (Button) dialog.findViewById(R.id.btn_cancel_proj);
okBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText editProjName = (EditText) dialog.findViewById(R.id.edit_proj_name);
String projName = editProjName.getText().toString();
if (rmProject == null) {
rmProject = new RMProject();
}
rmProject.setName(projName);
if (projectDBHelper == null) {
projectDBHelper = new RMProjectDBHelper(ProjectsActivity.this);
}
projectDBHelper.addProject(rmProject);
dialog.dismiss();
}
});
cancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
private String[] getProjectNames() {
LinkedList<RMProject> projects = (LinkedList<RMProject>) projectDBHelper.getAllProjects();
String[] names = new String[projects.size()];
int i = 0;
for (RMProject p : projects) {
names[i++] = p.getName();
}
return names;
}
}
Fragment with custom DbHelper class:
public class RMProjectDBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "RM_DB";
private static final String TABLE_PROJECT = "PROJECT";
private static final String[] COLUMNS = {"id_project", "project_name"};
private static final int DB_VERSION = 1;
public RMProjectDBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
//.....some code...
public void deleteProject(int id){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_PROJECT, "id_project = ?", new String[]{String.valueOf(id)});
db.close();
Log.d("deleteProject with id: ", Integer.toString(id));
}
public int findIdByName(String name){
SQLiteDatabase db = this.getReadableDatabase();
String selectQuery = "SELECT PROJECT.id_project FROM PROJECT WHERE PROJECT.project_name = '"+name+"'";
Cursor cursor = db.rawQuery(selectQuery,null);
int id=-1;
while (cursor.moveToNext()){
id = cursor.getInt(cursor.getColumnIndex("id_project"));
Log.i("LOGGING:"," FIND ID BY NAME: ID="+id);
}
return id;
}
on delete action fetch the data once again and then again call adapter.notifyDataSetChanged it will work
sir, how do i refresh my listview if i pressed the back button in android emulator? i've clicked an item on activityA then goes to an edit form in activityB. after saving updates, if i pressed the back button, it should refresh the list.
here is my activityA
public class CustomListView extends Activity {
final Context context = this;
public static String name;
public static String number;
int REQUEST_CODE = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
GroupDb info = new GroupDb(this);
info.open();
ArrayList<Contact> searchResults = info.getView();
MyCustomBaseAdapter mcba = new MyCustomBaseAdapter(CustomListView.this, searchResults);
mcba.updateResults(searchResults);
final ListView lv = (ListView) findViewById(R.id.srListView);
lv.setAdapter(new MyCustomBaseAdapter(this, searchResults));
info.close();
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
// TODO Auto-generated method stub
Object o = lv.getItemAtPosition(position);
final Contact fullObject = (Contact)o;
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
alertDialogBuilder
.setMessage("Select action")
.setCancelable(false)
.setPositiveButton("Edit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
Toast.makeText(getApplicationContext(), "Edit ", Toast.LENGTH_LONG).show();
name = fullObject.getName();
number = fullObject.getPhoneNumber();
Intent intent = new Intent();
intent.setClass(CustomListView.this, EditDetails.class);
startActivityForResult(intent, REQUEST_CODE);
}
})
.setNeutralButton("Delete", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
Toast.makeText(getApplicationContext(), "Delete ", Toast.LENGTH_LONG).show();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
});
}
public void onResume()
{ // After a pause OR at startup
super.onResume();
//Refresh your stuff here
GroupDb info = new GroupDb(this);
info.open();
ArrayList<Contact> searchResults = info.getView();
MyCustomBaseAdapter mcba = new MyCustomBaseAdapter(CustomListView.this, searchResults);
mcba.updateResults(searchResults);
info.close();
}
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == REQUEST_CODE) {
GroupDb info = new GroupDb(this);
info.open();
ArrayList<Contact> searchResults = info.getView();
MyCustomBaseAdapter mcba = new MyCustomBaseAdapter(CustomListView.this, searchResults);
mcba.updateResults(searchResults);
info.close();
}
}
//edit or delete list when clicked
public void deleteEditOption()
{
}//end deleteEditOption()
}
and here is my activityB
public class EditDetails extends Activity{
public String nameChanged;
public String numChanged;
public String name;
public String num;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.editdetails);
final EditText sqlName = (EditText)findViewById(R.id.editName);
final EditText sqlNumber = (EditText)findViewById(R.id.editNumber);
name = CustomListView.name;
num = CustomListView.number;
Button bUpdate = (Button)findViewById(R.id.editUpdate);
Button bView = (Button)findViewById(R.id.editView);
sqlName.setText(name);
sqlNumber.setText(num);
bUpdate.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
nameChanged = sqlName.getText().toString();
numChanged = sqlNumber.getText().toString();
GroupDb info = new GroupDb(EditDetails.this);
info.open();
long rowid = info.getRowId(name, num);
info.updateNameNumber(rowid+1, nameChanged, numChanged);
Toast.makeText(getApplicationContext(), rowid+" "+nameChanged+" "+numChanged, Toast.LENGTH_LONG).show();
ArrayList<Contact> searchResults = info.getView();
MyCustomBaseAdapter mcba = new MyCustomBaseAdapter(EditDetails.this, searchResults);
mcba.updateResults(searchResults);
Toast.makeText(getApplicationContext(), "Update Successful!", Toast.LENGTH_LONG).show();
info.close();
}
});
bView.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setClass(EditDetails.this, CustomListView.class);
startActivityForResult(intent, 0);
}
});
}
}
if i clicked this bView button in my activityB, it updates the listview. but pressing the back button just shows my previous unupdated listview. thanks for help in advance
edit
public class MyCustomBaseAdapter extends BaseAdapter {
private static ArrayList<Contact> searchArrayList;
private LayoutInflater mInflater;
public MyCustomBaseAdapter(Context context, ArrayList<Contact> results) {
searchArrayList = results;
mInflater = LayoutInflater.from(context);
}
public void updateResults(ArrayList<Contact> results) {
searchArrayList = results;
//Triggers the list update
notifyDataSetChanged();
}
public int getCount() {
return searchArrayList.size();
}
public Object getItem(int position) {
return searchArrayList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.custom_row_view, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView.findViewById(R.id.name);
holder.txtPhone = (TextView) convertView.findViewById(R.id.phone);
holder.status = (TextView) convertView.findViewById(R.id.status);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtName.setText(searchArrayList.get(position).getName());
holder.txtPhone.setText(searchArrayList.get(position).getPhoneNumber());
holder.status.setText(searchArrayList.get(position).getStatus());
return convertView;
}
static class ViewHolder {
TextView txtName;
TextView txtPhone;
TextView status;
}
}
Rewrite
While I recommend customizing a CursorAdapter to work with your database. Let's change a couple points with your current code:
First create a field variable for mbca, (just like name and number).
MyCustomBaseAdapter mcba;
Second update how you initialize mbca in onCreate():
mcba = new MyCustomBaseAdapter(EditDetails.this, searchResults);
//mcba.updateResults(searchResults); this line isn't necessary here
Third make a small change to onResume():
public void onResume()
{ // After a pause OR at startup
super.onResume();
//Refresh your stuff here
GroupDb info = new GroupDb(this);
info.open();
mcba.updateResults(info.getView());
info.close();
}
This works because updateResults() calls notifyDataSetChanged() and this updates the ListView automatically.
How would I use shared preferences to store the state of my checkbox for the next time the app is opened? I'm using a custom adapter so am guessing it has to be placed inside that but I'm not quite sure.
My Adapter:
public class MobileArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
private ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();
public MobileArrayAdapter(Context context, String[] values) {
super(context, R.layout.list_adapter, values);
this.context = context;
this.values = values;
for (int i = 0; i < this.getCount(); i++) {
itemChecked.add(i, false);
}
}
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.list_adapter,
parent, false);
}
// in your code you search for the CheckBox with the id checkBox1 2 times so I assumed that you are referring to the same view.
CheckBox cBox = (CheckBox) rowView.findViewById(R.id.checkBox1);
cBox.setTextColor(0xFFFFFFFF);
cBox.setText(values[position]);
cBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
itemChecked.set(position, true);
// do some operations here
} else {
itemChecked.set(position, false);
// do some operations here
}
}
});
cBox.setChecked(itemChecked.get(position));
return rowView;
}
}
My main Activity:
public class TheKevinAndEricaBoxActivity extends Activity {
/** Called when the activity is first created. */
private String[] myString;
private String list;
private String[] myString2;
private String list2;
private static final Random rgenerator = new Random();
private static final Random rgenerator2 = new Random();
MediaPlayer mp;
final Context mContext = this;
final Context context = this;
private Button button;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Resources res = getResources();
addListenerOnButton();
myString = res.getStringArray(R.array.myArray);
list = myString[rgenerator.nextInt(myString.length)];
myString2 = res.getStringArray(R.array.myArray2);
list2 = myString2[rgenerator.nextInt(myString2.length)];
}
public void addListenerOnButton() {
final Context context2 = this;
ImageButton ibg = (ImageButton) findViewById(R.id.buttongallery);
ibg.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent(context2, App2Activity.class);
startActivityForResult(intent, 0);
}
});
ImageButton ib = (ImageButton) findViewById(R.id.imagebutton1);
ib.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View erica) {
AlertDialog.Builder b = new AlertDialog.Builder(
TheKevinAndEricaBoxActivity.this);
b.setMessage(myString[rgenerator.nextInt(myString.length)]);
b.setTitle(R.string.title1);
b.setIcon(R.drawable.menuiconerica);
b.setPositiveButton("Back",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
dialog.cancel();
}
});
Dialog d = b.create();
d.show();
}
});
ImageButton ib2 = (ImageButton) findViewById(R.id.imagebutton2);
ib2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View kevin) {
AlertDialog.Builder b = new AlertDialog.Builder(
TheKevinAndEricaBoxActivity.this);
b.setMessage(myString2[rgenerator2.nextInt(myString2.length)]);
b.setTitle(R.string.title2);
b.setIcon(R.drawable.menuiconkevin);
b.setPositiveButton("Back",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
dialog.cancel();
}
});
Dialog d = b.create();
d.show();
}
});
ImageButton Ib3 = (ImageButton) findViewById(R.id.imagebutton3);
Ib3.setOnClickListener(new View.OnClickListener() {
public void onClick(View lemonclick) {
mp = MediaPlayer.create(getApplicationContext(),R.raw.lemonspeech);
mp.start();
}
});
button = (Button) findViewById(R.id.button01);
// add button listener
button.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// custom dialog
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.list);
dialog.setTitle("The List");
// set the custom dialog components - text, image and button
//TextView text = (TextView) dialog.findViewById(R.id.TextView01);
//text.setText("Did you not read the button? :P i'm not finshed on this yet XD");
ListView listView = (ListView) findViewById(R.id.myList);
String[] values = new String[] { "value1", "value2", };
MobileArrayAdapter mAdapter = new MobileArrayAdapter(getBaseContext(), values);
ListView mListView = (ListView) dialog.findViewById(R.id.myList);
mListView.setAdapter(mAdapter);
Button dialogButton = (Button) dialog.findViewById(R.id.Button01);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
});
}
}
In the OnCLickListener for your Button add this:
//...
// custom dialog
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.list);
dialog.setTitle("The List");
prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefsEditor = prefs.edit();
String currentlyStored = prefs.getString("checked_list", null);
int[] savedStatus = null;
if (currentlyStored != null) {
String[] tmp = currentlyStored.split(",");
savedStatus = new int[tmp.length];
for (int i = 0; i < tmp.length; i++) {
savedStatus[i] = Integer.parseInt(tmp[i]);
}
}
adapter = new MobileArrayAdapter(this, soundnames, savedStatus);
ListView mListView = (ListView) dialog.findViewById(R.id.myList);
mListView.setAdapter(mAdapter);
//...
where:
private SharedPreferences prefs;
private SharedPreferences.Editor prefsEditor;
private MobileArrayAdapter adapter;
are fields in your class with the ListView(the adapter field will hold your adapter object that you set on the list).
Modify the constructor of your custom adapter like this:
public MobileArrayAdapter(Context context, String[] values,
int[] oldStatus) {
super(context, R.layout.adapters_simpleplay_row, values);
this.context = context;
this.values = values;
// make every CheckBox unchecked and then loop through oldStatus(if
// not null)
for (int i = 0; i < this.getCount(); i++) {
itemChecked.add(i, false);
}
if (oldStatus != null) {
for (int j = 0; j < oldStatus.length; j++) {
itemChecked.set(oldStatus[j], true);
}
}
}
Also add the following method in your custom adapter MobileArrayAdapter:
public ArrayList<Boolean> getCheckedStatus() {
return itemChecked;
}
Last in the listener for your dialogButton add this:
dialogButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String toStore = "";
ArrayList<Boolean> status = adapter.getCheckedStatus();
for (int i = 0; i < status.size(); i++) {
if (status.get(i)) {
toStore += i + ",";
}
}
prefsEditor.putString("checked_list", toStore.equals("") ? null
: toStore.substring(0, toStore.length() - 1));
prefsEditor.commit();
dialog.dismiss();
}
});
To save selections make a method saveSelections and call it in onPause() and onDestroy(), or create a Button to do the same for you...
Edit:
Since you are using a ListView which is MultipleChoice I suppose you can do this in onCreate...
listView = (ListView) findViewById(R.id.list);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_multiple_choice,
android.R.id.text1, names));
Create these three methods outside onCreate()
private void LoadSelections() {
SharedPreferences sp = getPreferences(MODE_PRIVATE);
if (sp.contains(LOAD_LIST)) {
String savedItems = sp.getString(LOAD_LIST, "");
this.selectedItems.addAll(Arrays.asList(savedItems.split(",")));
int count = this.listView.getAdapter().getCount();
for (int i = 0; i < count; i++) {
String currentItem = (String) listView.getAdapter().getItem(i);
if (this.selectedItems.contains(currentItem)) {
this.listView.setItemChecked(i, true);
}
}
}
}
public void SaveSelections() {
SharedPreferences sp = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor prefEditor = sp.edit();
String savedItems = getSavedItems();
prefEditor.putString(LOAD_LIST, savedItems);
prefEditor.commit();
}
private String getSavedItems() {
String savedItems = "";
int count = listView.getAdapter().getCount();
for (int i = 0; i < count; i++) {
if (listView.isItemChecked(i)) {
if (savedItems.length() > 0) {
savedItems += "," + listView.getItemAtPosition(i);
} else {
savedItems += listView.getItemAtPosition(i);
}
}
}
return savedItems;
}
Then in onPause(), do this:
#Override
protected void onPause() {
SaveSelections();
super.onPause();
}
Then finally in onCreate call this..
LoadSelections();
You can make a string of 0 & 1 and store it using shared preference. The number of checkboxes (or the number of view) you are using will be the length of string. You save it accordingly.
Eg:
String s[]="0000000000";
for (i=0;i<s.length();i++)
if (checkboxAtLocation(i)==true) //checkboxAtLocation() will return a boolean variable on basis of its checked or not
s[i]=1;
Now store this string.
On starting activity again, use this string to set the checkbox.
This is bit complex to implement but most efficient way as per my knowledge.
I hope it solves your doubt.