I was recently working on a todo list application in android studio where the user will input text through an EditText, and then the String will be added to a listView as shown below.
public class MainActivity extends AppCompatActivity {
private ArrayList<String> items;
private ArrayAdapter<String> itemsAdapter;
private ListView lvItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvItems = (ListView) findViewById(R.id.lvItems);
items = new ArrayList<>();
itemsAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, items);
lvItems.setAdapter(itemsAdapter);
}
private void setupListViewListener() {
lvItems.setOnItemLongClickListener(
new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapter,
View item, int pos, long id) {
// Remove the item within array at position
items.remove(pos);
// Refresh the adapter
itemsAdapter.notifyDataSetChanged();
return true;
}
});
}
public void addTask(View v) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.dialog, null);
dialogBuilder.setView(dialogView);
final EditText edt = (EditText) dialogView.findViewById(R.id.edit1);
dialogBuilder.setTitle("Add a New Task");
dialogBuilder.setMessage("Enter what you want to do");
dialogBuilder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String itemText = edt.getText().toString();
itemsAdapter.add(itemText);
edt.setText("");
}
});
dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
});
AlertDialog b = dialogBuilder.create();
b.show();
}
}
But the problem I have is that when the user closes the activity, the state of the ListView will change back to it's original value.
I want the ListView to retain the Information that has been put inside it when the activity closes.
How do I go about this?
There are many ways to save data in your app.
You can use the following options:
SharedPreferences
Files
SQLite (with plain sql or with the framework Room)
For more information check this link : https://developer.android.com/training/data-storage/index.html
Usually for this situation using Sqlite
But you can use others way such as Shared preference or File
Like you can see here: https://developer.android.com/guide/topics/data/data-storage.html
Related
i'm trying to get into MVVM pattern and my problem is that I'm not really sure if I use it correctly. View is responsible for all UI operations (like show stuff?) but what happens when we need to change something in the logic.
So what I really wanna do is, show a dialog with certain options, pick one and reload the app.
I have implement the functions in MainActivity class and i use mCountrySelection.show() when action needed.
public void createCountriesDialog()
{
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MainActivity.this);
dialogBuilder.setTitle("Available Countries");
GridView gridView = new GridView(MainActivity.this);
final String[] countries = getResources().getStringArray(R.array.countries);
final String[] codes = getResources().getStringArray(R.array.codes);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, countries);
gridView.setAdapter(arrayAdapter);
dialogBuilder.setView(gridView);
dialogBuilder.setNegativeButton("Close", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
});
mCountrySelection = dialogBuilder.create();
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
PreferencesManager.setCountry(countries[position], codes[position]);
getSupportActionBar().setTitle(PreferencesManager.getCountry());
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.a_main_frame, new ArticlesFragment(), "ArticlesFragment");
fragmentTransaction.commit();
mCountrySelection.dismiss();
}
});
}
public void createAboutDialog()
{
AlertDialog.Builder aboutBuilder = new AlertDialog.Builder(MainActivity.this);
aboutBuilder.setTitle("Top News v1.0");
aboutBuilder.setMessage("Simple application for displaying Top Headlines from newsapi.org.\n\nIcons made by Freepik from www.flaticon.com.");
aboutBuilder.setNegativeButton("Close", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.dismiss();
}
});
mAbout = aboutBuilder.create();
}
Make 1 interface ItemClick and implement this interface from where you are calling Dialog.
public interface ItemClick{
public void onClick(int position, String country);
}
Pass this interface reference to your dialog method
public void createCountriesDialog(ItemClick listner)
{
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MainActivity.this);
dialogBuilder.setTitle("Available Countries");
GridView gridView = new GridView(MainActivity.this);
final String[] countries = getResources().getStringArray(R.array.countries);
final String[] codes = getResources().getStringArray(R.array.codes);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, countries);
gridView.setAdapter(arrayAdapter);
dialogBuilder.setView(gridView);
dialogBuilder.setNegativeButton("Close", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
listener = null;
}
});
mCountrySelection = dialogBuilder.create();
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
listener.onclick(position, countries[position]);
PreferencesManager.setCountry(countries[position], codes[position]);
getSupportActionBar().setTitle(PreferencesManager.getCountry());
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.a_main_frame, new ArticlesFragment(), "ArticlesFragment");
fragmentTransaction.commit();
mCountrySelection.dismiss();
}
});
}
Then when you click on grid item, using interface reference call onclick method
Now when you will receive a callback in onClick(int pos , String country)
Using your view model make api call and reload screen.
Set listener =null when dialog dismiss to avoid memory leaks
1- Expose a mutable LiveData or Observer in your ViewModel
public MutableLiveData<Pair<String, String>> countryInfo = new MutableLiveData<>()
2- Pass the user selection to the ViewModel
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
viewModel.countryInfo.setValue(new Pair(countries[position], codes[position]))
mCountrySelection.dismiss();
}
3- Run your use-case (business logic) in your ViewModel (uploading info to server, saving it in database, etc.)
4- Update View through exposing another Observable (in this case the same countryInfo will work)
In MainActivity observe the countryInfo:
viewmodel.countryInfo.observe(this, new Observer<String>() {
#Override
public void onChanged(#Nullable final String newName) {
// Update the UI
PreferencesManager.setCountry(countries[position], codes[position]);
getSupportActionBar().setTitle(PreferencesManager.getCountry());
getSupportFragmentManager().beginTransaction();
.replace(R.id.a_main_frame, new ArticlesFragment(), "ArticlesFragment");
.commit();
}
});
P.S: It is considered best if you move this line to ViewModel as it is contain part of business logic:
PreferencesManager.setCountry(countries[position], codes[position]);
Unable to instantiate activity Component, ClassCastExceptioI'm new to android and so i followed different tutorials to accomplish my task. I'm having an error and despite all efforts it's still unable to resolve. I've a main activity through which i call a positive active(if user selects "yes" on alert). The positive activity basically contains a listView of three items and i want to display the contacts of mobile when user clicks on the first item.
I put the code of contacts retrieving in the fragment class but it's giving the error of casting even when i didn't use simple intent to call the fragment.
The code for main activity is as follows:
public class activity_home extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Context context = this;
new AlertDialog.Builder(context)
.setTitle("Alert")
.setMessage("Do you want to enable the app right now?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog,int id) {
// go to a new activity of the app
Intent positiveActivity = new
Intent(getApplicationContext(),
PositiveActivity.class);
startActivity(positiveActivity);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.setNeutralButton("Remind Me later", new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int
which) {
// do nothing
}
}
)
.
setIcon(android.R.drawable.ic_dialog_alert)
.show();
}}
PositiveActivity.java:
public class PositiveActivity extends FragmentActivity {
ListView listView;
ArrayList<String> listname;
ArrayList<String> list_no;
Context context;
LayoutInflater inflater;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.positive_view);
Context context = this;
listView = (ListView) findViewById(R.id.mobile_list);
TextView textView = new TextView(context);
textView.setTypeface(null, Typeface.BOLD);
textView.setHeight(100);
textView.setText("Define Specifications for Enabling Auto Pickup!");
listView.addHeaderView(textView);
// Array of strings...
String[] mobileArray = new String[] {"Add Numbers to the list","Select
Timer","Pick Selection Mode"};
final ArrayAdapter <String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
mobileArray);
listView.setAdapter(adapter);
// ListView Item Click Listener
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// ListView Clicked item index
int itemPosition = position;
// ListView Clicked item value
String itemValue = (String)
listView.getItemAtPosition(position);
if (itemPosition == 1) {
ContactListFragment fragmentS1 = new ContactListFragment();
getSupportFragmentManager().beginTransaction().replace
(R.id.headlines_fragment,
fragmentS1).commit();
}}});}}
And the code of Fragment:
import android.support.v4.widget.SimpleCursorAdapter;
public class ContactListFragment extends ListFragment implements
LoaderCallbacks<Cursor> {
private CursorAdapter mAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// create adapter once
Context context = getActivity();
int layout = android.R.layout.simple_list_item_1;
Cursor c = null; // there is no cursor yet
int flags = 0; // no auto-requery! Loader requeries.
mAdapter = new SimpleCursorAdapter(context, layout, c, FROM, TO, flags);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// each time we are started use our listadapter
setListAdapter(mAdapter);
// and tell loader manager to start loading
getLoaderManager().initLoader(0, null, this);
}
// columns requested from the database
private static final String[] PROJECTION = {
Contacts._ID, // _ID is always required
Contacts.DISPLAY_NAME_PRIMARY // that's what we want to display
};
// and name should be displayed in the text1 textview in item layout
private static final String[] FROM = { Contacts.DISPLAY_NAME_PRIMARY };
private static final int[] TO = { android.R.id.text1 };
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// load from the "Contacts table"
Uri contentUri = Contacts.CONTENT_URI;
// no sub-selection, no sort order, simply every row
// projection says we want just the _id and the name column
return new CursorLoader(getActivity(),
contentUri,
PROJECTION,
null,
null,
null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Once cursor is loaded, give it to adapter
mAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// on reset take any old cursor away
mAdapter.swapCursor(null);
}
}
I'll be grateful if someone points out the mistake in code
try using add instead of replace
getSupportFragmentManager().beginTransaction().add
(R.id.headlines_fragment, fragmentS1).commit();
I'm making a simple to do list and I want to be able to click on the item and enter a new text which will then replace the text of the TextView in that cell. I've got the dialogAlert working, I just don't know how to grab the cell's TextView and change it
This is what the Activity looks like,
public class MainActivity extends AppCompatActivity {
private ListDataSource ds;
private ListView listViewToDo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Context context = this;
Log.d("MainActivity","Attempting to create data source");
try {
ds = new ListDataSource();
}
catch(Exception e)
{
e.printStackTrace();
Log.d("MainActivity","Failed to create data source");
}
Log.d("Main Activity","Attempting to link empty list view to on screen view");
listViewToDo = (ListView)findViewById(R.id.listOfLists);
Log.d("Main Activity","Views linked, Attempting to set adapter to listView");
listViewToDo.setAdapter(new ListDataSourceAdapter(this, ds));
Log.d("Main Activity", "Successfully set Adapter");
// add button listener
listViewToDo.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id)
{
AlertDialog.Builder editItem = new AlertDialog.Builder(context);
final EditText edittext = new EditText(context);
editItem.setTitle("Change Item");
editItem
.setMessage("Set new todo item")
.setView(edittext)
.setCancelable(false)
.setPositiveButton("Submit", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
//what do I put here?
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
}
});
AlertDialog alertDialog = editItem.create();
alertDialog.show();
}
});
}
}
ds.remove(position);
ds.add(position,edittext.getText().toString().trim())
ListDataSourceAdapter adapter = new ListDataSourceAdapter(this, ds)
listViewToDo.setAdapter(adapter );
adapter.notifDataSetChanged();
I want to Edit my ListView items. for example; I have a listView item i clicked this item and I add string value with edit text afterwards I again click this item and I add new string value alongside to previous string value, and again, again, again. When I click this item I want edit this listitem. How I do that?
Java sourcecode:
public class MainActivity extends Activity {
TextView tvDers;
EditText etDers, etDersSaati;
EditText etNot;
LinearLayout LayoutDers;
ArrayAdapter<String> adapter;
ListView list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnDersEkle = (Button) findViewById(R.id.btnDersEkle);
list = (ListView) findViewById(R.id.listView1);
adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1);
etDers = new EditText(MainActivity.this);
//Dialog
AlertDialog.Builder build = new AlertDialog.Builder(MainActivity.this);
build.setTitle("Ders Ekle");
build.setView(etDers);
build.setPositiveButton("Tamam", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
adapter.add(etDers.getText().toString());
}
});
list.setAdapter(adapter);
final AlertDialog alertDers = build.create();
btnDersEkle.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
alertDers.show();
}
});
}
}
Save item values in ordering Collection. Set this collection in adapter. Add and remove this values and after call notifyDataSetChanged for adapter.
Try like this.
listView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
String item = (String) parent.getItemAtPosition(int position);
item += "YourText";
ArrayAdapter adapter = (ArrayAdapter ) parent.getAdapter();
adapter.insert(item, position);
}
Sorry, but now I can't test this code. So I can not say for sure that it is correct. Try different variants and you'll get.
UPDATE
From dialog clickListener you can try this:
#Override
public void onClick(DialogInterface dialog, int which) {
ArrayAdapter adapter = (ArrayAdapter ) listView.getAdapter();
String item = (String) listView.getSelectedItem();
item += "YourText";
adapter.insert(item, position);
}
I have a arraylist in which users can input their text. And it is displayed in the screen as a listview. That works, but when i try to get the values of the arraylist it says that: Invalid index 0, size is 0. So im guessing for some reason the listview isnt populating?
This is how I add values to the list:
public class ZaidejaiActivity extends ActionBarActivity implements View.OnClickListener{
public Button mBtnIstrinti;
public Button mBtnPrideti;
public Button mBtnPradeti;
public EditText mYrasytiVarda;
public ListView mZaidejai;
ArrayList<String> list = new ArrayList<String>();
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zaidejai);
mBtnPrideti = (Button) findViewById(R.id.pridėtiBtn);
mBtnPrideti.setOnClickListener(this);
mYrasytiVarda = (EditText) findViewById(R.id.VardoYrasymoBtn);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, list);
// set the mZaidejai variable to your list in the xml
mZaidejai = (ListView) findViewById(R.id.sarašas);
mZaidejai.setAdapter(adapter);
mZaidejai.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// remove item from List.
#Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
list.remove(position);
AlertDialog.Builder builder = new AlertDialog.Builder(ZaidejaiActivity.this);
builder.setMessage("Delete?");
builder.setTitle("Confirm Action");
builder.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
adapter.notifyDataSetChanged();
}
//checked.clear();
});
builder.setNegativeButton("Cancel", null);
builder.create();
builder.show();
}
});
mBtnPradeti = (Button) findViewById(R.id.žaistiBtn);
mBtnPradeti.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// count items
int i;
for (i = adapter.getCount() - 1; i >= 0; i--) {
String obj = adapter.getItem(i);
// send items to other activity
Intent pradetiZaidima = new Intent(v.getContext(), ZaidimasActivity.class);
pradetiZaidima.putExtra("playerList", obj);
startActivity(pradetiZaidima);
}
}
});
}
#Override
public void onClick(View v) {
String input = mYrasytiVarda.getText().toString();
if(input.length() > 0)
{
// add string to the adapter, not the listview
adapter.add(input);
// no need to call adapter.notifyDataSetChanged(); as it is done by the adapter.add() method
}else{
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Klaida:");
alertDialog.setMessage("Blogai yrašytas vardas");
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// here you can add functions
}
});
alertDialog.show();
}
}
EDIT
In this activity I want to get the values of the list:
public class ZaidimasActivity extends ZaidejaiActivity {
public TextView mZaidejas;
public TextView mKlausimas;
public Button mKitasKlausimas;
public Button mGryzti;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zaidimas);
/** //get the player list from ZaidejaiActivity
Bundle recdData = getIntent().getExtras();
String myVal = recdData.getString("playerList"); */
//show the first players name
mZaidejas = (TextView)findViewById(R.id.ZaidejoVardas);
mZaidejas.setText(list.get(0));
/** mGryzti = (Button)findViewById(R.id.GryztiMeniuBtn);
mKitasKlausimas = (Button)findViewById(R.id.KitasBtn);
mKitasKlausimas.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
*/
Unfortunately your list==empty. So add some values on it.
list.add("ABC");
list.add("XYZ");
and then setAdapter
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, list);
mZaidejai = (ListView) findViewById(R.id.sarašas);
mZaidejai.setAdapter(adapter);
Your not adding any values to it. And your list is empty and add some values to it like list.add("hyd");
list.add("city");
and pass those values to adapter
Rather doing
adapter.add(input);
Do
list.add(input);
adapter.notifyDataSetChanged();
So, as others have said you should change the adapter.add(input); on the onClick method to
list.add(input);
adapter.notifyDataSetChanged();
Also, on an unrelated matter, you should really move the list.remove(position); call to the following onClick method of the positive button, before the adapter.notifyDataSetChanged(); call, so it wont be removed if the user cancels the action :)
at the first time your list adapter is empty (getCount() = 0) and you do -1 in the for
mBtnPradeti.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// count items
int i;
if (adapter.getCount() > 0)
{
for (i = adapter.getCount() - 1; i >= 0; i--) {
String obj = adapter.getItem(i);
// send items to other activity
Intent pradetiZaidima = new Intent(v.getContext(), ZaidimasActivity.class);
pradetiZaidima.putExtra("playerList", obj);
startActivity(pradetiZaidima);
}
}
}
});
and for this code :
mZaidejas.setText(list.get(0));
but on Create your list is empty !!!