This question already has answers here:
custom listview adapter getView method being called multiple times, and in no coherent order
(12 answers)
Closed 7 years ago.
This is my XML
<RelativeLayout
android:id="#+id/preview_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/socialbottom"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Preview"
android:textColor="#color/white"
android:textStyle="bold" />
<ImageButton
android:id="#+id/close_preview_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="#drawable/close_btn" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/empty_view"
android:layout_below="#+id/preview_header">
<ListView
android:id="#+id/preview_dialog_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:divider="#android:color/transparent"
android:dividerHeight="8dp"
android:scrollbars="none"></ListView>
</RelativeLayout>
<View
android:id="#+id/empty_view"
style="#style/Space"
android:layout_width="match_parent"
android:layout_above="#+id/preview_add_more_btn"></View>
<Button
android:id="#+id/preview_add_more_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/empty_view1"
android:background="#color/content_text"
android:drawableLeft="#drawable/plus_icon"
android:drawablePadding="50dp"
android:gravity="center_horizontal"
android:padding="8dp"
android:paddingLeft="300dp"
android:text="#string/add_more"
android:textColor="#color/white" />
<View
android:id="#+id/empty_view1"
style="#style/Space"
android:layout_width="match_parent"
android:layout_above="#+id/footer_preview"></View>
<RelativeLayout
android:id="#+id/footer_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<EditText
android:id="#+id/preview_input_timeline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:background="#color/acticty_textbox"
android:hint="What's up, admin?"
android:inputType="textMultiLine"
android:padding="8dp" />
<Button
android:id="#+id/preview_post_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/preview_input_timeline"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:background="#drawable/savebox"
android:padding="8dp"
android:text="Post"
android:textAllCaps="true"
android:textColor="#color/white"
android:textStyle="bold" />
</RelativeLayout>
This is JAVA
public View getView(int position, View convertView, ViewGroup parent) {
convertView = mInflater.inflate(R.layout.preview_list_view, null);
ImageButton removeBtn = (ImageButton) convertView.findViewById(R.id.remove_preview);
ImageView imageView = (ImageView) convertView.findViewById(R.id.preview_image);
VideoView videoView = (VideoView) convertView.findViewById(R.id.preview_video);
Log.e("video sizzzessssssss", String.valueOf(imagesList.size()));
if (SocialActivity.MEDIA_TYPE_IMAGE == previewType) {
videoView.setVisibility(View.INVISIBLE);
imageView.setVisibility(View.VISIBLE);
String path = imagesList.get(position);
File imgFile = new File(path);
if (imgFile.exists()) {
// Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
// imageView.setImageBitmap(myBitmap);
Bitmap d = new BitmapDrawable(context.getResources(), imgFile.getAbsolutePath()).getBitmap();
int nh = (int) (d.getHeight() * (512.0 / d.getWidth()));
Bitmap scaled = Bitmap.createScaledBitmap(d, 512, nh, true);
imageView.setImageBitmap(scaled);
}
} else {
imageView.setVisibility(View.INVISIBLE);
videoView.setVisibility(View.VISIBLE);
videoView.setVideoPath(imagesList.get(position));
MediaController mediaControls = new MediaController(SocialActivity.socialActivity);
videoView.setMediaController(mediaControls);
videoView.start();
videoView.pause();
Log.e("path video", imagesList.get(position));
}
removeBtn.setOnClickListener(new ListCustomClickEvents(callback, position));
return convertView;
}
You have to use the setTag() and getTag()
like these
public class ViewHolder {
//Declare yours all component here
// like below example
private ImageView profile_iv;
private TextView name_tv;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
///Firstly check the convertView is null or not like below
final ViewHolder _viewHolder;
if (convertView == null) {
_viewHolder = new ViewHolder();
LayoutInflater _layInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = _layInflater.inflate(R.layout.connection_friend_item, null);
///Finds yours layout items id here like below example
_viewHolder.profile_iv = (ImageView) convertView.findViewById(R.id.profile_iv);
_viewHolder.name_tv = (TextView) convertView.findViewById(R.id.name_tv);
convertView.setTag(_viewHolder);
} else {
_viewHolder = (ViewHolder) convertView.getTag();
}
////Set the data in the layout's item as below
_viewHolder.name_tv.setText(imagesList.get(position));
_viewHolder.profile_iv.setImageBitmap(imagesList.get(position));
return convertView;
}
I think you should use View Holder design pattern enables you to access each list item view without the need for the look up, saving valuable processor cycles. Specifically, it avoids frequent call of findViewById() during ListView scrolling, and that will make it smooth.
Refer below code for Demo:
public static class ViewHolder{
public TextView aliasTextView;
public TextView numTextView;
public TextView statusTextView;
public RelativeLayout mainLayout;
public NetworkImageView _profileImageView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
final ViewHolder holder;
LayoutInflater inflater = (LayoutInflater)_context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
DisputeListBean bean = _ArrayList.get(position);
if(convertView == null)
{
holder = new ViewHolder();
v = inflater.inflate(R.layout.dispute_row, null,false);
holder.mainLayout = (RelativeLayout)v.findViewById(R.id.mainLayout);
holder.aliasTextView = (TextView)v.findViewById(R.id.user_name);
holder.statusTextView = (TextView)v.findViewById(R.id.user_status);
holder._profileImageView = (NetworkImageView)v.findViewById(R.id.profile_pic);
v.setTag(holder);
}else {
holder = (ViewHolder) v.getTag();
}
holder.aliasTextView.setText(bean.getAlias_name().toUpperCase());
return v;
}
Don't give listview's height as wrap_content. When you the height as wrap_content, the listview will first populate few list items to determine the actual height of the listview
Due to inner caching mechanism in ListView, Android will be fire two times getView method for each visible item. It happens only for first time, when you open Activity/Fragment/View that contains a ListView. For more information refer to google with ScrapViews ListView request.
To solve your problem you need just check
if(convertView == null)
convertView = inflate...
or use ViewHolder pattern from Google.
Related
I've set up a grid of ImageViews with TextView overlays. My ImageAdapter code is as follows:
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
View grid;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
grid = new View(mContext);
grid = inflater.inflate(R.layout.image, null);
TextView textView = (TextView)grid.findViewById(R.id.mastery_text);
imageView = (ImageView)grid.findViewById(R.id.mastery_image);
grid.setLayoutParams(new GridView.LayoutParams(150, 150));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
grid.setPadding(8, 8, 8, 8);
grid.setBackgroundResource(R.color.orange);
imageView.setImageResource(mThumbIds[position]);
} else {
grid = (View) convertView;
}
return grid;
}
The corresponding XML layout for my ImageAdapter is this:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_practitioner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/mastery_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="bottom"
android:background="#bbffffff"
android:focusable="false"
android:focusableInTouchMode="false" >
<TextView android:id="#+id/mastery_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:textColor="#color/black"
android:gravity="bottom|center"
android:textSize="12sp"
android:textAllCaps="true"
android:paddingBottom="0dp"
android:text="3/3"
/>
</LinearLayout>
</FrameLayout>
XML code for my GridView (activity class):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="4"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center" />
</LinearLayout>
Here is the onCreate method of my main activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_masteries);
GridView gridview = (GridView) findViewById(R.id.gridview);
ImageAdapter adapter = new ImageAdapter(this);
gridview.setAdapter(adapter);
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(Masteries.this, "" + position,
Toast.LENGTH_SHORT).show();
}
});
}
I want to, after initializing the grid with the images, change one of the ImageViews from my activity class, given its position on the grid. How would I do that?
I'm not asking to change the image in response to an onItemClick.
Thanks in advance!
Edit:
I'm thinking of creating a changeImage(int position, int imageId) method in my Adapter and calling that from my activity class. Is that the right approach?
In your adapter:
public void updateImage(int position, int resourceId)
{
mThumbIds[position] = resourceId;
notifyDataSetChanged();
}
In your activity:
mAdapter.updateImage(<position>, <image_resource_id>);
Notes
You will have to make the adapter a member of your activity
The main idea is that you modify the backing data and and notify the GridView that this has changed and it is time to be redrawn
Your getView() method implementation needs a lot of improvement. It will cause lots of bugs once the system starts recycling the views (the convertView parameter comes in != null for a position different than it was used for last time)
Here's a sketch of how your getView() should look like:
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder viewHolder;
LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.image, parent, false);
// next three lines would not be necessary if:
// a) it is the same for every item;
// b) you inflate properly (using the parent);
// c) you specify this in the item's xml (R.layout.image)
convertView.setLayoutParams(new GridView.LayoutParams(150, 150));
convertView.setPadding(8, 8, 8, 8);
convertView.setBackgroundResource(android.R.color.holo_red_light);
viewHolder = new ViewHolder();
viewHolder.mTextView = (TextView)convertView.findViewById(R.id.mastery_text);
viewHolder.mImageView = (ImageView)convertView.findViewById(R.id.mastery_image);
// this could also be set in xml perhaps
viewHolder.mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
}
// update the values every time we are being asked to update the item,
// because the item might have been reused from a different position
viewHolder.mImageView.setImageResource(mThumbIds[position]);
//viewHolder.mTextView.setText("myText");
return convertView;
}
public static class ViewHolder
{
TextView mTextView;
ImageView mImageView;
}
You can set a unique id to each ImageView using names (See here) or even integer numbers with a sequence or something (increasing at each image you put in the view).
Another good way to do this is using the tags, with setTag() and getTag().
This question has a good answer: What is the main purpose of setTag() getTag() methods of View?
I'm learning Android, and following this tutorial on custom ListView Items.
However, I've created my own ListView item and when I load up the app (on my Galaxy S4, physical device) it becomes incredibly slow.
When I use a simple_list_item_1 for my listview, everything runs smooth, but when I use my own custom item it runs super slow. I can't find out why this is. There seem to be no expensive (and definitely not infinitely running) operations that I created.
I've also noticed that even tho I have only 5 listItems, the getView method gets called around 15 times. An explanation to why this is would also be welcome. (They might be related)
For my Activity I used Android Studio (1.2.2) standard "Navigation Drawer Activity". I've only been adding stuff in the onCreateView method. Which now looks like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
/* Start of my custom code */
//Create some list items
String[] words = {"Defenestration", "Indicative", "Executive", "Developmental", "Consciousness"};
//The list in the Fragment
ListView list = (ListView) rootView.findViewById(R.id.mainList);
//The custom ListAdapter
ListAdapter la = new ShaggyAdapter(getActivity(), words);
//A built in listadapter for testing
//ListAdapter la2 = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, words);
list.setAdapter(la);
//Create listener
list.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String word = String.valueOf(parent.getItemAtPosition(position));
Toast.makeText(getActivity(), word, Toast.LENGTH_SHORT).show();
}
});
/* End of my custom code */
return rootView;
}
The custom adapter looks like this:
class ShaggyAdapter extends ArrayAdapter<String>{
private static final String TAG = "coo";
public ShaggyAdapter(Context context, String[] words) {
super(context, R.layout.shaggy_item, words);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(getContext());
if (convertView == null){
convertView = inflater.inflate(R.layout.shaggy_item, parent, false);
Log.i(TAG, "inflate");
}else{
Log.i(TAG, "Don't inflate");
}
String word = getItem(position);
TextView name = (TextView) convertView.findViewById(R.id.itemName);
name.setText(word);
return convertView;
}
}
The custom List Item looks like this:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:columnCount="5">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="#+id/itemImage"
android:layout_row="0"
android:layout_column="0"
android:src="#drawable/no_profile"
android:layout_margin="8dp"
android:layout_rowSpan="2"
android:contentDescription="#string/shaggy_item_image_description" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/shaggy_item_name_placeholder"
android:id="#+id/itemName"
android:layout_row="0"
android:layout_column="1"
android:layout_margin="8dp"
android:layout_marginTop="14dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/shaggy_item_new_tag"
android:id="#+id/itemNew"
android:layout_row="0"
android:layout_column="2"
android:layout_marginTop="14dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/shaggy_item_date_placeholder"
android:id="#+id/itemDate"
android:layout_row="1"
android:layout_column="1"
android:layout_margin="8dp"
android:layout_columnSpan="2" />
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:id="#+id/itemStar"
android:layout_row="0"
android:layout_column="3"
android:src="#drawable/rating_star_1"
android:layout_margin="8dp"
android:layout_marginTop="14dp"
android:layout_rowSpan="2"
android:contentDescription="#string/shaggy_item_star_description" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/shaggy_item_rating_placheholder"
android:id="#+id/itemRating"
android:layout_row="0"
android:layout_column="4"
android:layout_margin="8dp"
android:layout_marginTop="14dp"
android:layout_rowSpan="2" />
</GridLayout>
Any suggestions would be highly appreciated.
I found the answer, I made a very silly mistake. The image I was using in the profile image view was 2000x2000px and I displayed it in a 80x80dp imageview. I noticed memory usage suddenly doubled.
Using a smaller image (currently 300x300px) made everything run super smooth. What I've learned today:
- Use correctly sized images! Android doesn't like handling images.
I will also be using the Holding Pattern as suggested by Boss and King of Masses to make it extra smooth.
why findViewById is so slow? And why View Holder
Pattern is faster?
When you are not using Holder so getView() method will call findViewById() as many times as you row(s) will be out of View. So if you have 1000 rows in List and 990 rows will be out of View then 990 times will be called findViewById() again.
Holder design pattern is used for View caching - Holder (arbitrary) object holds child widgets of each row and when row is out of View then findViewById() won't be called but View will be recycled and widgets will be obtained from Holder.
if (convertView == null) {
convertView = inflater.inflate(layout, null, false);
holder = new Holder(convertView);
convertView.setTag(holder); // setting Holder as arbitrary object for row
}
else { // view recycling
// row already contains Holder object
holder = (Holder) convertView.getTag();
}
// set up row data from holder
titleText.setText(holder.getTitle().getText().toString());
Where Holder class can looks like:
public class Holder {
private View row;
private TextView title;
public Holder(View row) {
this.row = row;
}
public TextView getTitle() {
if (title == null) {
title = (TextView) row.findViewById(R.id.title);
}
return title;
}
}
Here is second approach how to use ViewHolder pattern:
ViewHolder holder;
// view is creating
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.row, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
}
// view is recycling
else {
holder = (ViewHolder) convertView.getTag();
}
// set-up row
final MyItem item = mItems.get(position);
holder.title.setText(item.getTitle());
...
private static class ViewHolder {
public TextView title;
public ImageView icon;
}
This Android listview using ViewHolder will help you to implement the same.
As everybody know, Google and AppCompat v7 as support library released new ViewGroup called RecyclerView that is designed for rendering any adapter-based views.
Cheers !!
I want to implement grid, which will be populated dynamically. I want to know what is the best approach to implement this Relative layout(List View) or Grid Layout?
You can generate a GridView dynamically.
GridView would contain of ImageView and TextView as per your need. You will have to use your custom adapter. In it's getView method, populate the ImageView and TextView.
Example:
GridView item.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imgItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/txtItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="trebuchet"
android:textColor="#android:color/black"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
Java code:
A POJO class for item:
public class Item
{
String title;
Drawable image;
//getter setter
}
Adapter class:
//getView method in your adapter class
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View itemView = convertView;
ViewHolder holder = null;
if (itemView == null)
{
final LayoutInflater layoutInflater =
(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
itemView = layoutInflater.inflate(resourceId, parent, false);
holder = new ViewHolder();
holder.imgItem = (ImageView) itemView.findViewById(R.id.imgItem);
holder.txtItem = (TextView) itemView.findViewById(R.id.txtItem);
itemView.setTag(holder);
}
else
{
holder = (ViewHolder) itemView.getTag();
}
Item item = getItem(position);
holder.imgItem.setImageDrawable(item.getImage());
holder.txtItem.setText(item.getTitle());
return itemView;
}
Now add adapter data in your Activity class and then set that adapter to GridView.
Refer to this and this
Hope it helps.
Simply use GridView with a custom adapter. Each time you want the view to update, call notifyDataSetChanged() on the adapter.
You want GridView. Easy example here. In your case, you will need to make an XML layout for each row to accommodate both your TextView and ImageView. Other answers here address that.
Im new to android and Im building an app to show stock prices from an XML feed.
I have got an array list containing 3 items. However, I want to change the color of one of the items in the array list to red if its -ve or green if its +ve.
I dont know how to do this or where in my code is best to do it.
Please help....
My Adapter class:
public class TheAdapter extends ArrayAdapter<TheMetal>{
public TheAdapter(Context ctx, int textViewResourceId, List<TheMetal> sites) {
super(ctx, textViewResourceId, sites);
}
#Override
public View getView(int pos, View convertView, ViewGroup parent){
RelativeLayout row = (RelativeLayout)convertView;
Log.i("StackSites", "getView pos = " + pos);
if(null == row){
LayoutInflater inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = (RelativeLayout)inflater.inflate(R.layout.row_metal, null);
}
TextView dispNameTxt = (TextView)row.findViewById(R.id.displayNameText);
TextView spotPriceTxt = (TextView)row.findViewById(R.id.spotPriceText);
TextView changeTxt = (TextView)row.findViewById(R.id.changeText);
dispNameTxt.setText (getItem(pos).getDisplayName());
spotPriceTxt.setText(getItem(pos).getSpotPrice());
changeTxt.setText(getItem(pos).getChange());
return row;
}
My row_metal layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp" >
<TextView
android:id="#+id/displayNameText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:layout_marginLeft="20dp" />
<TextView
android:id="#+id/spotPriceText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/displayNameText"
android:textSize="19sp"
android:textStyle="bold"
android:gravity="right"
android:layout_alignParentRight="true"
android:layout_marginRight="30dp" />
<TextView
android:id="#+id/changeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/spotPriceText"
android:layout_toRightOf="#+id/displayNameText"
android:textSize="16sp"
android:gravity="right"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
/>
It is so simple. You just need to place these line within your getView() method:
if (Double.parseDouble(getItem(pos).getChange())>=0) {
row.setBackgroundColor(Color.parseColor("#00FF00");
changeTxt.setTextColor(Color.parseColor("#00FF00"));
} else {
row.setBackgroundColor(Color.parseColor("#FF0000");
changeTxt.setTextColor(Color.parseColor("#FF0000"));
}
Change your getView() method to this
#Override
public View getView(int pos, View convertView, ViewGroup parent){
if(convertView == null)
convertView = getLayoutInflater().inflate(R.layout.row_metal, null);
TextView dispNameTxt = (TextView) convertView .findViewById(R.id.displayNameText);
TextView spotPriceTxt = (TextView) convertView .findViewById(R.id.spotPriceText);
TextView changeTxt = (TextView) convertView .findViewById(R.id.changeText);
dispNameTxt.setText(getItem(pos).getDisplayName());
spotPriceTxt.setText(getItem(pos).getSpotPrice());
changeTxt.setText(getItem(pos).getChange());
if( Double.parseDouble(getItem(pos).getSpotPrice()) >= 0 )
convertView.setBackgroundColor(Color.GREEN);
else
convertView.setBackgroundColor(Color.RED);
return convertView;
}
I need to make a ListView with this specific attributes:
1) Every row has a CheckBox on the left , seekbar below check box and textview below seekbar ;
2) The seekbar is active and only if the correlated CheckBox is checked.
3) textview displays progress of seekbar
Please help me
Create a ListView in your main layout file first
<ListView
android:id="#+id/colorStockList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/vehicleOption"
android:divider="#b5b5b5"
android:dividerHeight="1dp" >
</ListView>
and a separate layout file which will contain your checkbox, seekbar and textview. Create other layout file as if it's a view in itself. Ex:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<TextView
android:id="#+id/colorCode"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:gravity="start"
android:textAppearance="?android:attr/textAppearanceMedium" />
<SeekBar
android:id="#+id/countSeekBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:progress="20"
android:secondaryProgress="20" />
<EditText
android:id="#+id/countEditText"
android:layout_height="50dp"
android:layout_width="wrap_content"
android:gravity="end"
android:inputType="number" />
</RelativeLayout>
Now you can use ViewHolder to populate this list. Sample ViewHolder for above example
public class ColorStockListViewAdapter extends ArrayAdapter<Color> {
Context context;
public ColorStockListViewAdapter(Context context, int resourceId,
List<Color> items) {
super(context, resourceId, items);
this.context = context;
}
/* private view holder class */
private class ViewHolder {
// ImageView vehicleImageView;
TextView colorDesc;
SeekBar seekBar;
EditText countText;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Color rowItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.color_stock_list, null);
holder = new ViewHolder();
holder.colorDesc = (TextView) convertView
.findViewById(R.id.colorCode);
holder.seekBar = (SeekBar) convertView
.findViewById(R.id.countSeekBar);
holder.countText = (EditText) convertView
.findViewById(R.id.countEditText);
holder.seekBar.setTag(holder.countText);
holder.countText.setTag(holder.seekBar);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.colorDesc.setText(rowItem.getDescription());
holder.seekBar.setMax(100);
holder.countText.setText("0");
return convertView;
}
}
And this is how you'll call it in your Activity file
ColorStockListViewAdapteradapter = new ColorStockListViewAdapter(this,
R.layout.activity_sales_list, colors);
where your activity_sales_list is our layout file you created to populate in ListView. Also to attach checkbox to seekbar and seekbar to checkbox, use setTag(), ex:
checkbox.setTag(seekbar);
Now the seekbar for a checkbox can be fetched like
SeekBar seekbar = checkbox.getTag();