How do I paint every value that under 100 in red in my ListView?
i have ListView that connect to my_list.xml
i connect the cursor like this:
public void update_list(String NN) {
c = db.rawQuery(NN, null);
startManagingCursor(c);
String[] from = new String[]{"_id","Store","Makat","Des","Qty" };
int[] to = new int[]{R.id.txtID, R.id.txtStore,R.id.txtMakat ,R.id.txtDes ,R.id.txtQty};
SimpleCursorAdapter notes = new SimpleCursorAdapter (this, R.layout.my_list, c, from, to);
setListAdapter(notes);
}
How to do it ?
My suggestion would be to make your own adapter which would extend SimpleCursorAdapter. In it, you should override the getView method which creates every row view.
class MyCustomAdapter extends SimpleCursorAdapter{
private Context context;
private Cursor c;
public MyCustomAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;
}
#Override
public View getView(int pos, View inView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
this.c.moveToPosition(pos);
//get the value from cursor, evaluate it, and set the color accordingly
int columnIndexOfQty = 4;
int qty = c.getInt(columnIndexOfQty);
if(qty < 100){
rowView.setBackgroundColor(Color.RED);
}
return rowView;
}
}
There may be some errors, but I think that you must get the idea.
Related
i have created a custom array adapter for my list view but for some reason the data is not getting displayed in listview item. even the log cat doesnt show anything when i put log statement in getView method of the custom adapter which extends ArrayAdapter.
This is the activity that holds listview
public class booktable extends AppCompatActivity {
ListView mylv;
int[] array = new int[5];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_booktable);
mylv = findViewById(R.id.mylv);
array = new int[]{1, 0, 0, 0, 1};
ListAdapter la = new customadapter(getApplicationContext(),R.layout.activity_booktable,array);
mylv.setAdapter(la);
}
}
this is my custom adapter
public class customadapter extends ArrayAdapter {
LayoutInflater li;
int[] table = new int[5];
public customadapter(#NonNull Context context,int resource, int [] array) {
super(context,resource);
li = LayoutInflater.from(context);
table = array;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View v = li.inflate(R.layout.custom_row,parent);
ImageView img = v.findViewById(R.id.img);
TextView tv = v.findViewById(R.id.tv);
if(table[position]==0)
{
tv.setText("FULL");
tv.setTextColor(Color.RED);
}
if(table[position]==1)
{
tv.setText("AVAILABLE");
tv.setTextColor(Color.GREEN);
}
return v;
}
}
try to pass the parameter array or collection to ArrayAdapter constructor, Looks like this:
public customadapter(#NonNull Context context,int resource, int [] array) {
super(context, resource, array);
li = LayoutInflater.from(context);
table = array;
}
I have some issues looping through all objects in a listview that uses my own custom adapterclass. The idea is that for each row where a checkbox is checked, something happens. Now, the function checkBoxCount correctly identifies the number of checked boxes and which position. However, when i check more than one box i get:
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0
The error occurs at the row where i assign the listitem to "f".
void checkBoxCount(){
for (int i = 0; i < list.getCount(); i++) {
CheckBox cb = list.getChildAt(i).findViewById(R.id.checkBoxSendAnytimerTo);
if (cb.isChecked()){
Log.d("i= ",String.valueOf(i));
f = (Friend) list.getItemAtPosition(i);
}
}
}
This is my adapter because i feel like somethings going wrong there:
public class SendAnytimerAdapter extends ArrayAdapter<Friend> {
ArrayList<Friend> friendList = new ArrayList<>();
public SendAnytimerAdapter(Context context, int textViewResourceId, ArrayList<Friend> objects) {
super(context, textViewResourceId, objects);
friendList = objects;
}
#Override
public int getCount() {
return super.getCount();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v;
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.send_anytimer_adapter_layout, null);
TextView textView1 = (TextView) v.findViewById(R.id.textViewSendAnytimerAdapterName);
TextView textView2 = (TextView) v.findViewById(R.id.textViewSendAnytimerAdapterCount);
textView2.setText(friendList.get(position).getAnytimerCountFriend());
textView1.setText(friendList.get(position).getfriendUserName());
return v;
}
Any clues on where my mistake lies?
Thanks in advance!
You need to override the method getCount
#Override
public int getCount() {
return friendList.size();
}
Update :
the Grid is now displayed correctly, but the content is missing
I checked
String text[] = getResources().getStringArray(R.array.main_table);
and text is filled with the Strings and if I use the code in the activity file the data is shown.
Any ideas
Original Question
I am having problems using findViewById() in non-activity classes.
If I am on the top Level, it is no problem.
((Activity)context).findViewById(R.id.statistic_grid);
But when I am trying to reference child views, I am getting "null"
View view = super.getView(position, convertView, parent);
TextView tv = (TextView) view.findViewById(R.id.statistic_cell_text);
Can please anybody help me out.
Thanks in advance
Lars
public class MainStatisticGridView extends GridView {
public MainStatisticGridView(Context context) {
super(context);
GridView statistic = (GridView) ((Activity)context).findViewById(R.id.statistic_grid);
String[] from = new String[]{"text"};
int[] to = new int[]{R.id.statistic_cell_text};
List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();
String text[] = getResources().getStringArray(R.array.main_table);
for (int i = 0; i < text.length; i++) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("text", text[i]);
fillMaps.add(map);
}
SimpleAdapter adapter = new MyCursorAdapter(((Activity)context), fillMaps, R.layout.calendar_title_cell, from, to);
statistic.setAdapter(adapter);
}
private class MyCursorAdapter extends SimpleAdapter {
public MyCursorAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Set<Integer> VALUES = new HashSet<Integer>(Arrays.asList(
new Integer[]{0, 1, 2, 3, 4, 5, 10, 15, 20}
));
View view = super.getView(position, convertView, parent);
if (VALUES.contains(Integer.valueOf(position))) {
view.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
TextView tv = (TextView) view.findViewById(R.id.statistic_cell_text);
tv.setTextColor(getResources().getColor(R.color.statistic_title));
view.setPadding(0, 0, 0, 0);
} else {
view.setBackground(getResources().getDrawable(R.drawable.border_intern));
}
return view;
}
}
}
You need to inflate the layout, like this. Once you inflate the layout you can get the child items.
private class MyCursorAdapter extends SimpleAdapter {
//private variables
Context context;
LayoutInflater inflater;
public MyCursorAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.context = context;
//get layoutinflater
inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Set<Integer> VALUES = new HashSet<Integer>(Arrays.asList(
new Integer[]{0, 1, 2, 3, 4, 5, 10, 15, 20}
));
//inflate your layout
if(convertView==null)
{
convertView = inflater.inflater(layoutfile, parent,false);
}
if (VALUES.contains(Integer.valueOf(position))) {
convertView.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
TextView tv = (TextView) convertView.findViewById(R.id.statistic_cell_text);
tv.setTextColor(getResources().getColor(R.color.statistic_title));
convertView.setPadding(0, 0, 0, 0);
} else {
convertView.setBackground(getResources().getDrawable(R.drawable.border_intern));
}
return convertView;
}
}
Please note I did not test this.
The ImageAdapter code I used to display images from my SD card to a GridView causes the images to repeat. The same set of images, like 10 of them are repeated in the GridView.
Here's my Adapter code:
private class ImageAdapter extends BaseAdapter {
private Context context;
public ImageAdapter(Context localContext) {
context = localContext;
}
public int getCount() {
return cursor.getCount();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView picturesView;
if (convertView == null) {
picturesView = new ImageView(context);
// Move cursor to current position
cursor.moveToPosition(position);
// Get the current value for the requested column
int imageID = cursor.getInt(columnIndex);
// Set the content of the image based on the provided URI
picturesView.setImageURI(Uri.withAppendedPath(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, "" + imageID));
picturesView.setScaleType(ImageView.ScaleType.CENTER_CROP);
picturesView.setPadding(0, 0, 0, 0);
picturesView.setLayoutParams(new GridView.LayoutParams(300, 300));
}
else {
picturesView = (ImageView)convertView;
}
return picturesView;
}
}
Additionally, here's the code that calls the Adapter in order to display all my SD Card images in the GridView
String[] projection = {MediaStore.Images.Thumbnails._ID};
// Create the cursor pointing to the SDCard
cursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection, // Which columns to return
null, // Return all rows
null,
MediaStore.Images.Thumbnails._ID);
// Get the column index of the Thumbnails Image ID
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID);
GridView sdcardImages = (GridView) findViewById(R.id.sdcard);
sdcardImages.setAdapter(new ImageAdapter(this));
// Set up a click listener
sdcardImages.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
// Get the data location of the image
String[] projection = {MediaStore.Images.Media.DATA};
cursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection, // Which columns to return
null, // Return all rows
null,
null);
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToPosition(position);
// Get image filename
String imagePath = cursor.getString(columnIndex);
// Use this path to do further processing, i.e. full screen display
}
});
What is wrong with my code guys?
In case the view is recycled and convertView is not null, you are not resetting the image URI. This is why you seeing just the images for which the view had to be created from scratch as convertView was null.
Therefore reuse or create a new view if needed :
final ImageView picturesView = convertView == null ? new ImageView(context) : (ImageView) convertView;
and later on configure it as you want.
But it is far more easier in you case to inherit behavior from CursorAdapter rather than BaseAdapter abstract class :
private class ImageAdapter extends CursorAdapter {
private final int columnIndex;
public ImageAdapter(Context context, Cursor cursor) {
super(context, cursor, true);
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return new ImageView(context);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
final ImageView picturesView = (ImageView) view;
final int imageID = cursor.getInt(columnIndex);
final Uri uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(imageID));
picturesView.setImageURI(uri);
picturesView.setScaleType(ImageView.ScaleType.CENTER_CROP);
picturesView.setPadding(0, 0, 0, 0);
picturesView.setLayoutParams(new GridView.LayoutParams(300, 300));
}
}
I have an app that loads data from a sqllite database, then converts the data to appropriate formats so it could pass on the data to fragment tabs.
Everything works fine except for the images.
In the DB images are stored in full path, for example R.drawable.muntjakas and the images are available in the resource drawable folder.
The app pulls the data from the db and then converts it to int format so it could be passed on. Eclipse is not giving me any errors, but when the app loads images are not displayed. My xml files have the image id set up and displays the images if I assign the values manually for example
flag = new int[] { R.drawable.muntjakas,.... };
What's the problem?
fragmenttab1.java class that loads data from sql and converts it:
public class FragmentTab1 extends SherlockFragment {
ListView list;
ListViewAdapter adapter;
private static final String DB_NAME = "animalsDB.sqllite3";
private static final String TABLE_NAME = "animals";
private static final String ANIMAL_ID = "_id";
private static final String ANIMAL_NAME = "name";
private static final String ANIMAL_PIC = "pic";
public static final String[] ALL_KEYS = new String[] {ANIMAL_ID, ANIMAL_NAME,ANIMAL_PIC };
private SQLiteDatabase database;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragmenttab1, container,
false);
ExternalDbOpenHelper dbOpenHelper = new ExternalDbOpenHelper(getActivity(), DB_NAME);
database = dbOpenHelper.openDataBase();
Cursor cursor = getAllRows();
ArrayList<String> nameArray = new ArrayList<String>();
ArrayList<Integer> picArray = new ArrayList<Integer>();
for(cursor.moveToFirst(); cursor.moveToNext(); cursor.isAfterLast()) {
nameArray.add(cursor.getString(cursor.getColumnIndex(ANIMAL_NAME)));
picArray.add(cursor.getInt(cursor.getColumnIndex(ANIMAL_PIC)));
}
final String[] name = (String[]) nameArray.toArray(new String[nameArray.size()]);
final Integer[] pic = (Integer[]) picArray.toArray(new Integer[picArray.size()]);
final int[] flag = new int[pic.length];
for (int i = 0; i < pic.length; i++ ) {
flag[i] = pic[i];
}
// Locate the ListView in fragmenttab1.xml
list = (ListView) rootView.findViewById(R.id.listview);
// Pass results to ListViewAdapter Class
adapter = new ListViewAdapter(getActivity(), name, flag);
// Binds the Adapter to the ListView
list.setAdapter(adapter);
// Capture clicks on ListView items
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Send single item click data to SingleItemView Class
Intent i = new Intent(getActivity(), SingleItemView.class);
// Pass all data country
i.putExtra("country", name);
// Pass all data flag
i.putExtra("flag", flag);
// Pass a single position
i.putExtra("position", position);
// Open SingleItemView.java Activity
startActivity(i);
}});
return rootView;
}
public Cursor getAllRows() {
String where = null;
Cursor c = database.query(true, TABLE_NAME, ALL_KEYS,
where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
}
My listViewAdapter.java class that should load the data on the screen:
package kf.kaunozoo;
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context context;
String[] country;
int[] flag;
LayoutInflater inflater;
public ListViewAdapter(Context context, String[] country, int[] flag) {
this.context = context;
this.country = country;
this.flag = flag;
}
public int getCount() {
return country.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
// Declare Variables
TextView txtcountry;
ImageView imgflag;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.listview_item, parent, false);
// Locate the TextViews in listview_item.xml
txtcountry = (TextView) itemView.findViewById(R.id.country);
// Locate the ImageView in listview_item.xml
imgflag = (ImageView) itemView.findViewById(R.id.flag);
// Capture position and set to the TextViews
txtcountry.setText(country[position]);
// Capture position and set to the ImageView
imgflag.setImageResource(flag[position]);
return itemView;
}
}
What am I doing wrong? All answers are appreciated
I have had this problem once in one of my apps, however, what I did was, I saved unique ids for each drawable in database as I had limited images. While displaying I wrote a small function where I used switch statement to check for each id from database and then loaded images accordingly in ImageView.
However, when you have lots of images, try to use below function, where you can provide image names dynamically from database.
// image from res/drawable
int resID = getResources().getIdentifier("your_image_name",
"drawable", getPackageName());
Also, you may try the solution given at this blog.