When ListView is ready? - android

I want to change the background of a TextView, which is inserted in a ListView. The ListView contains a series of TextView, and the value of each one is retrieved from a simple List. Now I show you my snippet:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.town_selection);
list = (ListView) findViewById(R.id.list);
adapter = new ArrayAdapter<>(this, R.layout.string_item, App.towns);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
adapter.notifyDataSetChanged();
list.invalidate();
// list.getCount() returns zero!!
// and so, list.getChildAt(...) returns null!!
}
App.towns is the list of String I was talking, and its length is greater than 0. When the app is running it seems ok, because the ListView is showing the items, but at the end of the onCreate I need to change the background color of some items, but the ListView seems not ready as I commented.
notifyDataSetChanged() and invalidate() doesn't help.

I'm not claiming that my answer is the best, but I have some idea and I'd like to share it.
If your string list of towns, as I understood, is unchangable let's do the following:
...
final Context context = this;
String [] towns = new String [] { "town_1", "town_2", "town_3" };
ListView list;
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.town_selection);
list = (ListView) findViewById(R.id.list);
adapter = new ArrayAdapter<String>(this, R.layout.string_item, R.id.string_item_text, towns)
//R.id.string_item_text - id your TextView in item of your list
{
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
TextView txtView = (TextView) v.findViewById(R.id.string_item_text);
String sText = txtView.getText().toString();
if (sText.equals("town_1")) {
txtView.setBackgroundColor(Color.parseColor("#93C47D")); //#93C47D - just example
} else if (sText.equals("town_2")){
txtView.setBackgroundColor(Color.parseColor("#6FA8DC")); //#6FA8DC - just example
} else if (sText.equals("town_3")){
txtView.setBackgroundColor(Color.parseColor("#F6B26B"));//#F6B26B - just example
}
return v;
}
};
list.setAdapter(adapter);
...
It helped me in one of Android projects. If it will help you it'll be good.
In any way, leave your feedback.

You will need to write a custom adapter for your list view and change the color when creating each item in the list view.
This SO question - Custom Adapter for List View has great answers which should help you with how to create this custom adapter. You will not be able to do it with the ArrayAdapter as-is.

The best solution is to use a custom adapter instead of ArrayAdapter , then in the getView() method of custom adapter you can change the color of the textview

If, for some reason, you need to change your background is TextViev, the information about it should be somewhere to store and change the background is using methods in your custom adapter. Create your own custom adapter.

Related

How to Highlight the Item (Listview) of Next Activity After Clicking the Item(Listview) of Previous Activity?

I have two Fragments. One Fragment Consist of Questions While OtherFragment consist of Answers. For Example If one person click on Question(8) It means u can say that Item No 8, then it should go to next activity and highlight the Answer (8) of that Question. I am stuck. I shall be thank full to you.
Here is Some Code Which are sending Question No or list Item no to next Activity and next Activity code receiving this Question no and i saved it into Interger "a". Now what type of IF condition can work in the Next Activity?
First Activity
lst.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int index = position + 1;
Intent it = new Intent(this.getActivity(), NextActivity.class);
it.putExtra("Qlist", index);
startActivity(it);
}
Next Activity
Intent it = getActivity().getIntent();
int a = it.getIntExtra("Qlist", 0);
String result=String.valueOf(a);
Toast.makeText(getActivity(), ""+a, Toast.LENGTH_LONG).show();
ListView Adapter code of First Activity (using SQlite)
DatabaseAccess db=DatabaseAccess.getInstance(getActivity().getApplicationContext());
List<String> lst;
db.open();
lst=db.getexamq();
db.close();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(ExamQ.this.getActivity(), android.R.layout.simple_list_item_1, lst);
lv.setAdapter(adapter);
ListView Adapter code of Next Activity (using SQlite)
DatabaseAccess db=DatabaseAccess.getInstance(getActivity().getApplicationContext());
List<String> lst;
db.open();
lst=db.getexamq();
db.close();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(ExamA.this.getActivity(), android.R.layout.simple_list_item_1, lst);
lv.setAdapter(adapter);
Use the intent Bundle to move the questionId or question No to the next activity
In the adapter of the Questions ListView, set a different background color for the question with a similar questionId. You can even set the background to have a fade animation or change to normal after a certain number of milliseconds or seconds.
ALL THE CODE REQUIRED IS A LOT Write something(some code), and we can help on the ListViewAdapter in case it doesn't work
EDIT: SAMPLE FAST CUSTOM ADAPTER CODE
lv.setAdapter(new ArrayAdapter(ExamQ.this.getActivity(), android.R.layout.simple_list_item_1, android.R.id.text1, lst){
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
final String examQ = lst[position];
if (v == null) {
LayoutInflater vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(android.R.layout.simple_list_item_1, null);
}
TextView tv = (TextView) v.findViewById(android.R.id.text1);
tv.setText(examQ);
if( examQ.equals(result)) { // Unique identifier here
v.setBackground(Color.RED); //Some other fancy color here
}
return v;
}
});
However, I just discovered you do not have a unique identifier for each question. So for the time being just use the question string and pass it to the next activity
Suppose You have a textview for each answer in the listview of second fragment. Then you can compare the question id in the getView() of adapter of listview in second fragment. Now when you find your answer just call textview.setBackgroundColor().
Edit:
After lv.setAdapter (adapter); add
View v = lv.getViewAt(a);
if(v!=null)
v.setBackgroundColor (Color.RED);

Setup Listview to strikethrough item after click

good day, i have a problem here with my listview
i have a listview with custom arrayadapter which is have 12 item
i have already set the listview when click it's get strikethrough on the selected item
UPDATE
public class MainActivity extends AppCompatActivity {
private ListView mainList;
private final String[] listContent = {
"1. Get Ready",
"2. Second ",
"3. Third",
"4. Fourth",
"5. Fifth",
"6. Sixth",
"7. Seventh",
"8. Eight",
"9. Nineth",
"10. Ten",
"11. Eleven",
"12. Twelve",
"13. Look up number twelve",
"14. Its become strikethrough too",
"15. how to fix it?",
"16. Please help",
"17. Thanks",
"18. End" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainList = (ListView) findViewById(R.id.listview2);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, listContent);
mainList.setAdapter(adapter);
mainList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view,
int position, long id) {
TextView text = (TextView) view;
text.setPaintFlags(text.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
}
});
}
}
my problem is, when i click the first item (number one) and then it become strikethrough but the 12 item (number twelve) it's also strikethrough to.
see my picture
clicking first item:
https://i.stack.imgur.com/M0nvm.jpg
number twelve also get strikethrough
https://i.stack.imgur.com/1hTPM.jpg
This is because it is the same View instance that is being used now that the first item is out of view.
For this purpose you will need to implement your own (Base)Adapter and store the information there as to which items should be strike through.
Then set the correct paint flags in the getView method as the views move in and out of view.
This is happening because of a view is reused. You need to store the position OR id of that object and provide stroke through effect accordingly. Hope it will help you out. For code reference or help please refer below link.It will definitely help you out
http://lalit3686.blogspot.com/2012/06/today-i-am-going-to-show-how-to-deal.html
https://www.codeproject.com/Questions/896462/Android-Need-to-save-checkbox-state-in-a-custom-ad

Change Specific TextView Color in Listview

i Have Two Database
first one Contain All The Items, and the ListView Display it
and the second db contain the the Favorite item , [selected from the first database]
what i want is that when the listview display all the items
check if the item is already exist in Favoritelist then make that textview background RED for this item
i have this code that work fine
public static void ChangeMyFavoritesBG(){
for (int i = 0; i < Items.size(); i++) {
if(db.verification(Items.get(i).toString())){
try {
TextView favtextview = (TextView) listview.getChildAt(i-listview.getFirstVisiblePosition()).findViewById(R.id.item_name);
favtextview.setBackgroundResource(R.drawable.redcolor);
}catch (NullPointerException e) {
}}}}
db.verification check if item exist in favorites database
if true . then it should change the background of this item to red
this code work fine but only if i put it in button click
i need to make the code work automatically
but if i made it start automatically when the activity is loaded i get NullPointer Error
i guess because the function ChangeMyFavoritesBG(); work before the listview display items
any idea guys? and sorry for my bad english
Do this control inside the getView(int position, View convertView, ViewGroup parent) method of the Adapter used by the listView.
If your favorite is not currently visible in the ListView then getChildAt() will return null.
You are looping over all items in the list view and my guess is that it holds more items than can fit on the screen. When your favorite item is one of them then this fragment of your code
listview.getChildAt(i-listview.getFirstVisiblePosition())
will return null. And that will cause the NullPointerException when you call findViewById(R.id.item_name) on it.
Just add a check for null on the result of getChildAt(). If it is null then do nothing, if it is non-null then call the second part. This will protect against the exception when your favorite item is not on the screen, and will allow it to be colored red when your favorite is visible on the screen.
update
My apologies, I read to quickly and misunderstood your problem to be about the NullPointerException but you say that your code works fine when you call it from a button click handler but not when you call it automatically at start-up.
You are right, the ListView does not yet have any items loaded when you are still in onCreate(). You can add a delay before running you code. The following works for me:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
// initialize the ListView with data for the list items. (I'm using a string array in this
// example. You are loading it from a database table, but that is the same in principle.)
ListAdapter adapter = new ArrayAdapter<String>(this, R.layout.item_list, R.id.item_name, Items);
ListView listview = (ListView) findViewById(R.id.listview);
listview.setAdapter(adapter);
// ask the system to wait before setting the background color of the favorite item so that
// the ListView has time to load the items.
final int DELAY_IN_MILLISECONDS = 100;
listview.postDelayed(new Runnable() {
#Override
public void run() {
ChangeMyFavoritesBG();
}
}, DELAY_IN_MILLISECONDS);
}
As you can see in the above example, after initializing the ListView, you ask the system to wait 100 milliseconds before calling ChangeMyFavoritesBG(). Hopefully that is enough time to load the items from the database into the ListView. If it is not enough time then you can, of course, use a longer delay.
The alternative
The above should work, but to be honest I would not write it this way. The above code is very brittle because it depends on the timing of how long it takes to load the items. I recommend that you put your background coloring into a customized adapter.
Because you want the items displayed in a customized way -- you want them to have a red background when it is the favorite one -- you should use a customized adapter. Override the bindView() function to make the background red when it is the favorite one or give it a normal background when it is not the favorite.
I don't know how you currently get the items from the database into your ListView, but inheriting from SimpleCursorAdaptor would work pretty well.
public class FavoritesItemAdapter extends SimpleCursorAdapter {
public FavoritesItemAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
// read the name from the database
int nameColumnIndex = cursor.getColumnIndexOrThrow("name");
String name = cursor.getString(nameColumnIndex);
// write the name to the TextView
TextView nameText = (TextView) view.findViewById(R.id.item_name);
nameText.setText(name);
// set the background to normal or to red, depending on if it is the favorite one or not
boolean isFavorite = db_verification(name);
if (isFavorite) {
nameText.setBackgroundResource(R.drawable.redcolor);
} else {
nameText.setBackgroundResource(android.R.color.transparent);
}
}
public boolean db_verification(String name) {
// this is a stub. You must use your own code here
return name.equals("the favorite one");
}
}
You can then throw away ChangeMyFavoritesBG() and initialize your ListView with the adapter in onCreate() like this.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Cursor cursor = readItemsFromDatabase();
String[] from = new String[] { "name_column" }; // mapping from database column name ...
int[] to = new int[] { R.id.item_name }; // ... to View ID in the item's layout.
FavoritesItemAdapter adapter = new FavoritesItemAdapter(this, R.layout.item_list, cursor, from, to, 0);
ListView listview = (ListView) findViewById(R.id.listview);
listview.setAdapter(adapter);
}
Good luck!

Android: How do I dynamically show/hide an element in a ListView item depending on the Array value?

im trying to create a ListView filled with items fetched from an API, and depending on a variable, I want to show/hide an TextView in my ListView item layout for that row.
My ListView item layout contains 3 TextViews. One is hidden on default using android:visibilty:"GONE".
I am using a this for my ListAdapter:
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
Attach to:
ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.main,
new String[] { "title", "info","comments", "score" },
new int[] { R.id.item_title, R.id.item_subtitle, R.id.post_comments, R.id.post_score });
setListAdapter(adapter);
final ListView lv = getListView();
So my question is, how can I iterate the whole list to check if "VariableA" == "something" then show the hidden TextView within that single item?
Or is there a way to dynamically Insert a TextView in that a single ListView item?
Thanks!
You should create Custom Adapter For Listview and write Some Logic in
public View getView(final int position, View convertView, ViewGroup parent) {
if("variable1".equals("something")){
//create view here For row
} else{
//create another view here For row
}
return row;
}
You do not have to implement getView() at all, using a custom view binder check your flag and set that view invisible or gone. Since you're already using a view binder its easier to implement than getView()

Stuck... need help.. Listview w/ Array Adapter

Ok, so I have this application that takes a adress strings (from values/xml) and parses it your current position) retuning a name, address and distance away. This is then picked up by an arrayadapter and put up on a listview. I cannot for the life of me get the list view to accept an onitemclick to start another activity, where I can launch a different view. I did have it where I was getting the row, name and address to show through to an alert dialog, but in my efforts to get it to launch an activity, I lost that.
So does anyone have any thoughts? I am using the following call to make my list and and arrays. This is stripped down, so assume I have all the imports and proper formatting. I know I am just missing something simple here...
public class Wf extends ListActivity {
private ArrayList<String> DistanceList;
private ArrayAdapter<String> aa;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Bind the ListView to an ArrayList of strings.
DistanceList = new ArrayList<String>();
ListView lv = (ListView)findViewById(R.id.ListView01);
aa = new ArrayAdapter<String>(getApplicationContext(),
R.layout.listbox_layout,
DistanceList);
lv.setAdapter(aa);
//Call to get distance... here
}
public void onListItemClick(ListView parent, View v,int position, long id) {
ListView lv = (ListView)findViewById(R.id.ListView01);
Toast.makeText(this, "You clicked", Toast.LENGTH_LONG).show();
}
From the ListActivity docs:
ListActivity has a default layout that
consists of a single, full-screen list
in the center of the screen. However,
if you desire, you can customize the
screen layout by setting your own view
layout with setContentView() in
onCreate(). To do this, your own view
MUST contain a ListView object with
the id "#android:id/list" (or list if
it's in code)
Your ListView does not have the correct ID. Your code is incomplete but I suspect the listener is not being registered with the ListView.

Categories

Resources