the App. Crashs when delete item from ListView - android

I have an SQLite table and in the certain activity I obtain all the names fom the table and populate a listview with these names.
Inside the listview listener, the user have can delete the selected item.
The problem is when I delete the item the app crashes.
Please take a look on my code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylocations);
tv_counter = (TextView) findViewById(R.id.counter);
tv_testCounter = (TextView) findViewById(R.id.testCounter);
lv = (ListView) findViewById(R.id.mylist);
mpoh = new MP_DB(this);
db = mpoh.getWritableDatabase();
cv = new ContentValues();
if (hasRecords()) {
Toast.makeText(getBaseContext(), getRowsNum()+" row(s)", Toast.LENGTH_SHORT).show();
get_MPNames();
arrayToArrayList();
setListView();
lv.setOnItemClickListener(listViewListener);
} else {
Toast.makeText(getBaseContext(), "NO RECORDS"+","+getRowsNum()+"rows", Toast.LENGTH_SHORT).show();
}
}
Here are the method to convert the array to arraylist, and the listview listener:
private void arrayToArrayList() {
int s = str.length;
al = new ArrayList<String>();
for (int i=0; i < s; i++) {
al.add(str[i]);
}
}
private int getRowsNum() {
return mpoh.getCurrentRowNumber();
}
OnItemClickListener listViewListener = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
pos = arg2;
showDialoge();
}
};
Here how I delete element from the DB and the ListView:
private void deleteMPfromListView(int pos) {
al.remove(pos);
adapter.notifyDataSetChanged();
Toast.makeText(getBaseContext(), al.size()+" rows left in list view", Toast.LENGTH_SHORT).show();
}
private void deleteMPFromDB(int pos) {
mpoh.deleteMP(pos);
Toast.makeText(getBaseContext(), getRowsNum()+" rows left in DB", Toast.LENGTH_SHORT).show();
}
private Boolean hasRecords() {
if (getRowsNum() == 0) {
return false;
} else {
return true;
}
}
private void setListView() {
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
android.R.id.text1, al);
lv.setAdapter(adapter);
}
private void get_MPNames() {
str = new String[getRowsNum()];
for (int i=0; i <= getRowsNum()-1; i++) {
str[i] = mpoh.getMP_Name(i+1);
} //tv_testCounter.setText(str[87]);
}

Removing from the database has nothing to do with removing them from the ListView. I have not code of your implementation but you may try something like this too dynamically add or remove items:
public class LVDemo extends ListActivity {
// handles the ListView data
ArrayAdapter<String> adapter;
// Items that are displayed
ArrayList<String> listItems=new ArrayList<String>();
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
listItems);
setListAdapter(adapter);
}
/**
* Remove item.
*/
public void removeItem(int index) {
listItems.remove(index);
adapter.notifyDataSetChanged();
}
}
In General: You change the the ArrayList containing the element and then notify the adapter for the ListView

Related

How to populate autocomplete textview based on the selection of first?

There are 2 autocomplete textview one for the city and one for the state. I want that when a user enters the state in autocomplete textview then based on state selection, city autocomplete text view should be automatically filled. Like the ecommerce app whenever someone enters the postal code in the address section then the city and state get automatically filled and also the user has the option to select.
MainActivity.java
public class MainActivity extends AppCompatActivity {
EditText edtxt_name_address, edtxt_email_address, edtxt_mobile_address, edtxt_alt_mob_address, edtxt_pincode, edtxt_addline1, edtxt_addline2;
Button buttonSaveAddress;
AutoCompleteTextView edtxt_city, edtxt_state;
private static final String KEY_STATE = "state";
private static final String KEY_CITIES = "cities";
private ProgressDialog pDialog;
private String cities_url = "http://api.androiddeft.com/cities/cities_array.json";
final List<State> statesList = new ArrayList<>();
final List<String> states = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edtxt_city = findViewById(R.id.edtxt_city);
edtxt_state = findViewById(R.id.edtxt_state);
loadStateCityDetails();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.select_dialog_item, states);
edtxt_state.setThreshold(1);//will start working from first character
edtxt_state.setAdapter(adapter);//setting the adapter data into the AutoCompleteTextView
//edtxt_city.setTextColor(Color.BLACK)
edtxt_state.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
buttonSaveAddress = findViewById(R.id.buttonSaveAddress);
buttonSaveAddress.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
saveAddress();
}
});
}
private void loadStateCityDetails() {
JsonArrayRequest jsArrayRequest = new JsonArrayRequest
(Request.Method.GET, cities_url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray responseArray) {
try {
//Parse the JSON response array by iterating over it
for (int i = 0; i < responseArray.length(); i++) {
JSONObject response = responseArray.getJSONObject(i);
String state = response.getString(KEY_STATE);
JSONArray cities = response.getJSONArray(KEY_CITIES);
List<String> citiesList = new ArrayList<>();
for (int j = 0; j < cities.length(); j++) {
citiesList.add(cities.getString(j));
}
statesList.add(new State(state, citiesList));
states.add(state);
Log.d("lskd", String.valueOf(statesList));
Log.d("lskd", String.valueOf(states));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//pDialog.dismiss();
//Display error message whenever an error occurs
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(jsArrayRequest);
}
private void saveAddress() {
if (TextUtils.isEmpty(city)) {
edtxt_city.setError("Please enter your City");
edtxt_city.requestFocus();
return;
}
if (TextUtils.isEmpty(state)) {
edtxt_state.setError("Please enter your State");
edtxt_state.requestFocus();
return;
}
Intent profile_next = new Intent(MainActivity.this, ProfileNextActivity.class);
startActivity(profile_next);
}
}
State.java
public class State {
private String stateName;
private List<String> cities;
public State(String stateName, List<String> cities) {
this.stateName = stateName;
this.cities = cities;
}
public String getStateName() {
return stateName;
}
public List<String> getCities() {
return cities;
}
}
State and city has one to many relation, I didn't particularly understand what you meant by automatically filled. If you want to populate the related cities of the selected state do the following.
Inside your edtxt_state.setOnItemSelectedListener
edtxt_state.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
statesList.get(position).getCities(); //get your cities from selected state
//set adapter or notify city list of your `edtxt_city` AutoCompleteTextView
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
try this...
edtxt_state.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
List<String> cityList = statesList.get(position).getCities();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.select_dialog_item, cityList);
edtxt_city.setThreshold(1);//will start working from first character
edtxt_city.setAdapter(adapter);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
set your adapter inside loadStateCityDetails(); after getting stateList
statesList.add(new State(state, citiesList));
states.add(state);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.select_dialog_item, states);
edtxt_state.setThreshold(1);//will start working from first character
edtxt_state.setAdapter(adapter);
EDIT
edtxt_state.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String selection = (String) parent.getItemAtPosition(position);
int pos = -1;
for (int i = 0; i < statesList.size(); i++) {
if (statesList.get(i).getStateName().equals(selection)) {
pos = i;
break;
}
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.select_dialog_item, statesList.get(pos).getCities());
edtxt_city.setThreshold(1);//will start working from first character
edtxt_city.setAdapter(adapter);//setting the adapter data into the AutoCompleteTextView
}
});
you must get stateList
set city adapter as above

Spinner with dynamic list is not working

_doctorSpinner = (Spinner) findViewById(R.id.input_doctor);
final ArrayList<String> docList = new ArrayList<String>();
DataUtil.getDoctorList(this.getApplicationContext(), new ServerCallBack() {
#Override
public void onSuccess(JSONObject result) {
}
#Override
public void onSuccess(String result) {
}
#Override
public void onSuccess(JSONArray result) {
ArrayList<String> list = new ArrayList<String>();
list.add("Select Doctor");
try {
for (int i = 0; i < result.length(); i++) {
list.add(result.getString(i));
}
docList.addAll(list);
} catch (JSONException e) {
}
}
});
final ArrayAdapter<String> docAdapter = new ArrayAdapter<String>(this, R.layout.support_simple_spinner_dropdown_item, docList);
docAdapter.notifyDataSetChanged();
docAdapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
_doctorSpinner.setAdapter(docAdapter);
_doctorSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
System.out.println(position);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
In the above code i am getting a list of strings from server and populating in the spinner. When the activity is loaded i am unable to see the first item in the list("Select a doctor"). But when i click on spinner, i could see the items and select. Again then selected item is not visible as selected. Could anybody help me?
Thanks in advance.
_doctorSpinner = (Spinner) findViewById(R.id.input_doctor);
final ArrayList<String> docList = new ArrayList<String>();
DataUtil.getDoctorList(this.getApplicationContext(), new ServerCallBack() {
#Override
public void onSuccess(JSONObject result) {
}
#Override
public void onSuccess(String result) {
}
#Override
public void onSuccess(JSONArray result) {
ArrayList<String> list = new ArrayList<String>();
list.add("Select Doctor");
try {
for (int i = 0; i < result.length(); i++) {
list.add(result.getString(i));
}
docList.addAll(list);
final ArrayAdapter<String> docAdapter = new ArrayAdapter<String>(this, R.layout.support_simple_spinner_dropdown_item, docList);
docAdapter.notifyDataSetChanged();
docAdapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
_doctorSpinner.setAdapter(docAdapter);
_doctorSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
System.out.println(position);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
} catch (JSONException e) {
}
}
});
webservice call work in background thread so ypou get list size zero when u set adapter so inialize and setadapter when call finish
Call notifyDataSetChanged(); after your data is added to the list.
#Override
public void onSuccess(JSONArray result) {
ArrayList<String> list = new ArrayList<String>();
list.add("Select Doctor");
try {
for (int i = 0; i < result.length(); i++) {
list.add(result.getString(i));
}
docList.addAll(list);
if (null != docAdapter)
docAdapter.notifyDataSetChanged();
} catch (JSONException e) {
}
}
EDIT :
My bad I read the question incorrectly.
If you cannot see the text inside your spinner try this:
ArrayAdapter<String> docAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, docList);
And I don't believe you need to use docAdapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);

app crashes when a block of code is included in a loop

I have a block of code creating arraylists, adapter and onclickitemlistener and it works great ONLY if it is meant to work once. I want to include the block in a loop so it's performed several times, but when I do so the app crashes when I want to go to that activity so the block does not run even once... what may be the reason?
public class MyClass extends Activity {
int c=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.quiz1);
final ArrayList<String> words = new ArrayList<String>();
TextView tvTo = (TextView) findViewById(R.id.tvTo);
ListView lvLV = (ListView) findViewById(R.id.lvLV);
DataWraper dwF = (DataWraper) getIntent().getSerializableExtra("data");
ArrayList<Word> wordList = dwF.GetWords();
for(Word w : wordList) {
words.add(w.GetSth()+"."+w.GetSthElse());
}
// do {
Generator set = new Generator(words);
ArrayList<String> s = set.GetQuizSet();
final String palabra = s.get(0).substring(s.get(0).indexOf(".")+1);
tvTo.setText(s.get(0).substring(0, s.get(0).indexOf(".")));
Collections.shuffle(s);
final ArrayList<String> sp = new ArrayList<String>();
for(String o : s) {
transl.add(o.substring(o.indexOf(".")+1));
}
MAdapter la = new MAdapter(MyClass.this, sp);
lvLV.setAdapter(la);
lvLV.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(sp.get(position).matches(palabra)) {
Toast.makeText(getBaseContext(), "Good", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getBaseContext(), "Not Good", Toast.LENGTH_LONG).show();
}
// c++;
}
});
// } while(c<5);
}
}
Looks like you're getting a StackOverflowError. You only increment c in the OnItemClickListener, so it's not getting incremented in onCreate(), and your while-loop is running endlessly.
Without knowing exactly what you're trying to accomplish, or what exactly all your classes are, I juggled your code a bit. You might want to structure your code more like this:
public class MyClass extends Activity
{
int c = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.quiz1);
final ArrayList<String> words = new ArrayList<String>();
TextView tvTo = (TextView) findViewById(R.id.tvTo);
ListView lvLV = (ListView) findViewById(R.id.lvLV);
DataWraper dwF = (DataWraper) getIntent().getSerializableExtra("data");
ArrayList<Word> wordList = dwF.GetWords();
for (Word w : wordList)
{
words.add(w.GetSth() + "." + w.GetSthElse());
}
final ArrayList<String> sp = new ArrayList<String>();
MAdapter la = new MAdapter(MyClass.this, sp);
lvLV.setAdapter(la);
lvLV.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
//*** Your call to generate() will go in here
//*** depending on where you want it
if (sp.get(position).matches(palabra))
{
Toast.makeText(getBaseContext(), "Good", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getBaseContext(), "Not Good", Toast.LENGTH_LONG).show();
}
}
}
);
}
private void generate()
{
if (c < 5)
{
Generator set = new Generator(words);
ArrayList<String> s = set.GetQuizSet();
final String palabra = s.get(0).substring(s.get(0).indexOf(".") + 1);
tvTo.setText(s.get(0).substring(0, s.get(0).indexOf(".")));
Collections.shuffle(s);
for (String o : s)
{
transl.add(o.substring(o.indexOf(".") + 1));
}
c++;
}
}
}

any advice or hints for refreshing ArrayAdapter?

here I have a Fragment, I use this code and everything works normally, and what I want to do is update my shown list if there is a new file, could you guys give any advice or hint?
CODE:
public class HomeFragment extends Fragment {
public static final String TITLE = "title";
private List<String> library = new ArrayList<String>();
private TextView tv;
private ListView lv;
private ArrayAdapter<String> adapter;
public static Handler handHF;
private String[] temp;
private Object UIlock = new Object();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.home_fragment, container,
false);
library = getLibraryList();
if (!library.isEmpty()) {
if (tv != null) {
tv.setVisibility(View.GONE);
} else {
temp = library.toArray(new String[library.size()]);
lv = (ListView) rootView.findViewById(R.id.library_list);
adapter = new ArrayAdapter<String>(rootView.getContext(),
android.R.layout.simple_list_item_1, temp);
lv.setAdapter(adapter);
setListener(lv);
tv = (TextView) rootView.findViewById(R.id.library_tv1);
tv.setVisibility(View.GONE);
tv = null;
}
} else {
tv = (TextView) rootView.findViewById(R.id.library_tv1);
tv.setText("No Manga found...");
}
return rootView;
}
#SuppressLint("HandlerLeak")
#Override
public void onResume() {
/*
* Fragment on pause state
*/
super.onResume();
handHF = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message msg) {
if (msg.what == 0) {
refreshAdapter();
}
}
};
}
private void setListener(ListView lv) {
/*
* Sets listener on listView
*/
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent myIntent = new Intent(view.getContext(),
ChapterActivity.class);
myIntent.putExtra(TITLE, parent.getItemAtPosition(position)
.toString());
startActivity(myIntent);
}
});
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(view.getContext(),
parent.getItemAtPosition(position).toString(),
Toast.LENGTH_SHORT).show();
return true;
}
});
}
private final List<String> getLibraryList() {
/*
* Returns List<String> of library
*/
List<String> l = new ArrayList<String>();
File dir = new File(Constants.UNDUH);
if (dir.exists()) {
File[] dirs = dir.listFiles();
for (File i : dirs) {
l.add(i.getName());
}
return l;
} else {
return l;
}
}
private void refreshAdapter() {
/*
* It will update library and
*/
synchronized (UIlock) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
if (tv != null) {
tv.setVisibility(View.GONE);
}
library = getLibraryList();
temp = library.toArray(new String[library.size()]);
lv = (ListView) getActivity().findViewById(
R.id.library_list);
adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, temp);
lv.setAdapter(adapter);
}
});
}
}
}
any advice will be appreciated, thank you!
Update your list of string which you are passing to the ListView in your case you are using
private String[] temp;
Use notifyDataSetChanged Method, just call this after your adapter and it will automatically adds more items to list if your temp[] increments.
like this
adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, temp);
lv.setAdapter(adapter);
adapter.notifyDataSetChanged();
Where you are adding more data into temp[]
add an extra line
((ArrayAdapter) lv.getAdapter()).notifyDataSetChanged();

How to reload a spinner in Android?

Can anybody tell me the code to reload a Spinner?
I have created a small app where I can add some items and delete unwanted items. The items added will be showed in a spinner. Once I select an item from the spinner and delete it clicking the Delete Button, The item is getting deleted from the database & I get a Toast displayed "Item Deleted". But its still showing in the spinner until I logout and logs in once again. Here, I think I need to reload the spinner once again on the Delete button click. Can anybody help me out to do that?
public class DeleteChildActivity extends Activity {
TextView name;
Button delete;
Spinner spinner2;
private String URL = "/ParentProfileServlet";
private String URL1 = "/ChildProfileServlet";
private String URL2 = "/DeleteChildServlet";
ArrayList<NameValuePair> postparameter;
public static int selectChildId;
public static String imei;
ParentDetailsMod parentModel;
private ArrayList<ChildDetails> childArray = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.delete_child);
delete = (Button) findViewById(R.id.B_delchild);
spinner2 = (Spinner) findViewById(R.id.childspinner);
childArray = new SelectParser().parseSelectXml(response);
ArrayList<String> stringArray = new ArrayList<String>();
for (ChildDetails childModel : childArray) {
String str;
str = childModel.getName();
stringArray.add(str);
}
// spinner = (Spinner) findViewById(R.id.spinner11);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
getApplicationContext(), android.R.layout.simple_list_item_1,
stringArray);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner2.setAdapter(adapter);
spinner2.setPrompt(getString(R.string.selectLabel));
spinner2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int position, long arg3) {
imei = childArray.get(position).getImei_num();
selectChildId = childArray.get(position).getChild_id();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// spinner.performClick();
// String id = spinner2.getSelectedItem().toString();
// selectChildId = id.substring(0, id.indexOf("--"));
postparameter = new ArrayList<NameValuePair>();
String parent_id = LoginPageActivity.id;
postparameter
.add(new BasicNameValuePair("parent_id", parent_id));
postparameter.add(new BasicNameValuePair("child_id",
selectChildId + ""));
String response = null;
try {
response = CustomHttpClient.executeHttpPost(URL2,
postparameter);
System.out.println("response:" + response);
if (response.trim().compareTo("success") == 0) {
Toast.makeText(getApplicationContext(),
"Child deleted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"Failed to delete", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
You can use notifyDataSetChanged(); method to reload the adapter or display the changed data.
You should delete the item from you adapter list and then call spinner.notifyDataSetChanged() method to refresh you spinner

Categories

Resources