Hello I'm currently trying to make my first app on android and I've gotten some problems. I'm trying to make a todo-list app so want some kind of input to be transformed into checkboxes. I've made it work with radio buttons using radioGroup. But when using Checkboxes with ListView it just doesn't work.
Here's my code:
public class MainActivity extends AppCompatActivity {
EditText t;
ListView listView;
ArrayList<CheckBox> checkList = new ArrayList<>();
int i = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void add(View view){
t = findViewById(R.id.input);
String s = t.getText().toString();
CheckBox check = new CheckBox(this);
checkList.add(check);
listView = findViewById(R.id.list);
checkList.get(i).setText(s);
listView.addView(checkList.get(i));
i++;
t.setText("");
}}
The app crashes saying something about adapterView
You're unfortunately doing something wrong here. You are trying to add your view to Listviews on
listView.addView(checkList.get(i));
This is not the correct way to use ListViews. You have to use an adapter. The adapter would need to provide data for the listview to load.
Please have a look at this tutorial for how to use listviews.
Below is a summary of the steps to use a listView correctly.
Create a new layout file (say custom_cell.xml) inside your layouts folder.
Insert a checkbox inside your custom_cell.xml and place an Id which you can use later to identify the checkbox
Create an adapter for your listview
Override the getView method
Inside the getView method, inflate a new cell using the custom_cell.xml or reuse an existing cell if provided
Reference the Checkbox by using the Id you provided in the custom_cell.xml file
Related
I'm beginner in android and i want to add an item to a ListView when i click on a button.
but when i do that , the ListView restarts and all the previous changes i made disappear.
how can i save the previous state of the ListView.
This is the MainActivity :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listMarks = (ListView) findViewById(R.id.list_marks);
btn_add = (Button) findViewById(R.id.btn_add);
final Mark mark = new Mark("", "", "", "");
final ArrayList<Mark> marks = new ArrayList<Mark>();
marks.add(marks.size(), mark);
adapter = new MarkLitViewAdapter(MainActivity.this, marks);
listMarks.setAdapter(adapter);
btn_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
marks.add(mark);
adapter.notifyDataSetChanged();
}
});
}
I made this changes but when click on add button an item is being add but previous changes disappear this is when i click on the add button
First off, I strongly suggest you use RecyclerView instead of ListView, if you aren't already. It's a categorically better version of ListView.
The function you are looking for is notifyItemInserted.
I wrote up a very simple example in Kotlin (also suggested learning if you want to continue in Android development, since it's the officially supported language now.)
The relevant snippet is below. Create an addItem function in your adapter which uses notifyItemInserted:
fun addItem(value: String) {
items.add(value)
notifyItemInserted(items.size)
}
And then in your button OnClickListener call that adapter function to add a new item.
Instead of doing adapter.insert(mark, marks.size()); you can use the adapter.notifyDataSetChanged(); functionality. Remove the final from here final ArrayList<Mark> marks = new ArrayList<Mark>(); and insert your Mark into this ArrayList and then do adapter.notifyDataSetChanged() inside the OnClickListener
Every time I run my app it crashes giving me a nullpointerexception, I want to programatically change my background depending on the scenario, here is my code:
Main Activity:
public class Activity extends AppCompatActivity {
ConstraintLayout layout;
String messageSafe = "Item is Safe for Consumption";
String messageUnSafe = "Item is NOT Safe for Consumption";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_information);
layout = new ConstraintLayout(this);
if (matched.length == 0) {
layout.setBackgroundResource(R.drawable.background_safe);
setContentView(layout);
changeColor("#00FF00");
messageView.setText(messageSafe);
}
else{
layout.setBackgroundResource(R.drawable.background_unsafe);
setContentView(layout);
changeColor("#FF0000");
messageView.setText(messageUnSafe);
}
ListView listContains = (ListView) findViewById(R.id.lvItemsFound);
ArrayAdapter<String> contains = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, foundItems);
listContains.setAdapter(contains);
ListView listRestricted = (ListView) findViewById(R.id.lvItemsRestricted);
ArrayAdapter<String> found = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, matched);
listRestricted.setAdapter(found);
}
You are losing reference to your old view because you changed the layout to a new ConstraintLayout object. This means you now don't have your ListView objects and other items in your XML because that View is gone. It's not the ContentView anymore. If you want to work on the existing layout, you need to give the root view an ID.
<constraintlayout android:id="#+id/container" ... />
Then you can reference that ID with findViewById(R.id.container) and use the object you get from it to change your background like you are doing.
Try this:
1. Give your root view an ID
2. Set a ConstraintLayout object with ConstraintLayout layout = findViewById(R.id.container) (Note: You can call it anything, not just container, I am just going off my example from above, since I gave it the ID 'container')
3. call setBackgroundResource() like you are doing.
4. No need to call setContentView() again, this was set in the beginning, and you do not want to reset it to a new view you just constructed like you were initially doing.
5. You shouldn't crash when trying to call setAdapter() to your ListView now because you don't have a reference to an object that isn't in your content view.
layout = (ConstraintLayout)findViewById(R.id.container);
if (matched.length == 0) {
layout.setBackgroundResource(R.drawable.background_safe);
changeColor("#00FF00"); //assuming this is some local function?
messageView.setText(messageSafe);
}
else{
layout.setBackgroundResource(R.drawable.background_unsafe);
changeColor("#FF0000");
messageView.setText(messageUnSafe);
}
You are trying to set the background by replacing the view of your activity (this is what setContentView() does). This causes a null pointer exception later because the old layout (defined in the XML) has been replaced, so your list view no longer exists.
Instead, you should get a reference to the existing root view (the ConstraintLayout, although if you're just setting background you can just reference it as a View, no need to be so specific), and set the background on it, like so:
findViewById(R.id.container).setBackgroundResource(R.drawable.unsafe);
You'll also need to give the containing layout an id in the existing layout XML:
<android.support.constraint.ConstraintLayout
android:id="#+id/container"
... etc.
In my Android manifest, I am specifying a parentActivityName in order to utilise the back button displayed in the activity.
I find this however re-calls onCreate of the previous activity, in which I do several network calls and set up a recycler view widget.
This causes the screen to refresh entirely, I'd like to avoid this and deal with the recyclerview and what new content to display and delete to ensure the user flow is not jolted.
I currently set my application up in onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_container_list);
final SwipeRefreshLayout swiperefreshContainerListRecyclerView = (SwipeRefreshLayout) this.findViewById(R.id.swiperefresh_container_list_recyclerview);
swiperefreshContainerListRecyclerView.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
refreshContainerList();
}
}
);
// Get a handle on our RecyclerView for interactin and setup
containerListRecyclerView = (RecyclerView) findViewById(R.id.container_list_recyclerview);
// Grab a new LayoutManager
containerListLayoutManager = new LinearLayoutManager(this);
// Grab a new adapter
List<ContainerModel> containers = new ArrayList<>();
containerListRecyclerAdapter = new ContainerListRecyclerViewAdapter(containers, this);
// Better performance as the size of our RecyclerView does not change
containerListRecyclerView.setHasFixedSize(true);
// Attach our LayoutManager to our RecyclerView
containerListRecyclerView.setLayoutManager(containerListLayoutManager);
// Wire up adapter for RecyclerView
containerListRecyclerView.setAdapter(containerListRecyclerAdapter);
cAdvisorService = new CAdvisorService();
cAdvisorService.fetchDataFromService(context, containerListRecyclerAdapter);
System.out.println("Running onCreate!");
}
I already have logic within my cAdvisorService to deal with removing and adding items into the RecyclerView.
How do I deal with the fact that onCreate is called each time, forcing new instances of my RecyclerView and cAdvisorService?
There way to achieve this by declaring your parent activity in your Android manifest as
android:launchMode="singleTop"
, see more at: How can I return to a parent activity correctly?
I am curious how I would go about adding an an editText variable to a list in another activity. I have created an arrayList that names are stored into as they are entered in the editText line. These are stored in the nameList variable in the class StartingActivity. How would i go about adding and showing these names into a ListView in another activity and class called ListActivity as shown. Thank you. Also, how do i refractor the names of classes and files without it just basically not making my program runable.
Code:
Class StartingActivity:
public void onClick_btnConfirm {
EditText editName = (EditText) findViewById(R.id.editName);
TextView textOutput = (TextView) findViewById(R.id.textOutput);
Intent intentList = new Intent(StartingActivity.this, ListActivity.class);
if(editName.length()!=0) {
nameList.add(editName.getText().toString());
editName.setText("");
}
//intentList.putExtra("Name", editName.toString());
startActivity(intentList);
}
Class ListActivity:
public class ListActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
ListView listView = (ListView) findViewById(R.id.listAthletes);
final StartingActivity nameList = new StartingActivity();
nameList.getNameList();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, nameList.getNameList());
listView.setAdapter(arrayAdapter);
arrayAdapter.notifyDataSetChanged();
}
}
You cannot run findviewbyid() for an id in another Activity.This answer might be of help to you. If that is not what you really want to go with, you can do two things:
Send Intents with the string.
Use a sharedPreference and write the string to a sharedPreference. SharedPreferences also have an OnChangeListener, so you will be able know if the preference has changed. In the onResume() of that activity , you can just read from the sharedPreference, and update the UI
Also take a look at AsyncTask here
As mentioned , you can also use the SQLite Database
Can anybody help me? I'm trying to create a ListView in Android, and I'm trying to load items into it using code (not using XML)
Here's the code that I have so far
tweetList = (ListView)this.findViewById(R.id.tweetListView);
TextView tv;
for(int i=0;i<20;i++)
{
tv = new TextView(this);
tv.setText("I'm a textView");
tweetList.addHeaderView(tv);
}
tweetList.invalidate();
What am I doing wrong? The items are not showing in runtime
EDIT: I changed the code as per the answers below and here's the code I have now
tweetList = (ListView)this.findViewById(R.id.tweetListView);
ArrayAdapter<TextView> aa = new ArrayAdapter<TextView>(this, R.id.tweetListView);
tweetList.setAdapter(aa);
TextView tv;
for(int i=0;i<20;i++)
{
tv = new TextView(this);
tv.setText("I'm a textView");
//tweetList.addHeaderView(tv);
aa.add(tv);
}
tweetList.invalidate();
I'm getting an exception now
11-10 01:32:16.002: ERROR/AndroidRuntime(867): android.content.res.Resources$NotFoundException: Resource ID #0x7f050030 type #0x12 is not valid
Why am I not able to add them dynamically now?
You need to use ArrayAdapter and add it to the ListView. Then just add elements to the ArrayAdapter dynamically.
For example:
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1);
tweetList.setAdapter(arrayAdapter);
// ...
arrayAdapter.add("New Item");
The header view is just a header, its not the items in the list. Your listview receives its contents through an Adapter. The ListView does not keep Views for its children, but its the adaptor who creates them and fills them with the appropiate data when they need to be shown at the screen. Search for basic tutorials on how to do this, there are lots out there; and remember adapters are the key.