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();
Related
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.
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've created something similar to a listview via a xml file containing an ImageView and TextView and using the LayoutInflater.
It seems I've done this in quite an unorthodox way, as I can't figure out how to actually style the listview (ideally I want to define the size as there's other content to be put on the same interface)
I've tried styling the LinearLayout inself, and putting the LinearLayout within a parent LinearLayout, including a ListView within the said file named 'list', trying to define a setContentView within the class which extends ListActivity.
I would love just to be able to include the custom listview control into a LinearLayout just like any other control, rather than the control being the entire UI.
public class ImageActivity extends ArrayAdapter<PlaceStore> {
private final Context context;
private final List<PlaceStore> places;
public ImageActivity(Context context, List<PlaceStore> places) {
super(context, R.layout.image_text_row, places);
this.context = context;
this.places = places;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.image_text_row, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label);
ImageView imageView = (ImageView) rowView.findViewById(R.id.logo);
textView.setText(places.get(position).getName());
return rowView;
}
public class FavouriteActivity extends ListActivity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.favourite);
FavouriteData data = new FavouriteData(this);
List<PlaceStore> pS = data.returnFileData();
setListAdapter(new ImageActivity(this, pS));
}
R.layout.image_text_row
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp" android:background="#drawable/background_type" >
<ImageView
android:id="#+id/logo"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:src="#drawable/androidmarker" >
</ImageView>
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#+id/label"
android:textSize="20sp" >
</TextView>
</LinearLayout>
My main layout main.xml has only a Button, a EditText and an empty ListView as below:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
>
<LinearLayout
android:id="#+id/input_area"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<EditText
android:id="#+id/input_field"
android:layout_height="40dip"
android:layout_width="fill_parent"
android:layout_weight="5"
/>
<Button
android:id="#+id/send_btn"
android:layout_width="60dip"
android:layout_height="30dip"
android:text="#string/send"
android:layout_weight="1"
/>
</LinearLayout>
<LinearLayout
android:id="#+id/output_area"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#006633"
android:visibility="gone"
>
<ListView
android:id="#+id/output_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10dip"
>
<!-- When "send" button in above input_area is pressed,
text from EditText field show here programmatically as a new row of the listview-->
</ListView>
</LinearLayout>
</LinearLayout>
As you see above, there are two child LinearLayout hosted by main LinearLayout.
The 1st child LinearLayout with id input_area consists of a EditText and a Button.
The 2nd child LinearLayout with id output_area is an LinearLayout with an empty ListView, AND its visibility is set to "gone".
The feature I am going to implement is very simple, that's in the input_area, when user input some text in the EditText field, and press the send button, then the input string should be shown in the output LinearLayout as a new row of the listview programmatically.
What I tried is the java code below:
EditText inputTxt = (EditText) findViewById(R.id.input_field);
Button sendBtn = (Button) findViewById(R.id.send_btn);
LinearLayout outputArea = findViewById(R.id.output_area);
//Updated by Saurabh
ListView lv = findViewById(R.id.output_list);
MyListAdapter mAdapter = new MyListAdapter(this, arraylist);
//Update finished
sendBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
int visibility = outputArea.getVisibility();
if(visibility==View.GONE)
// set ListView visible
outputArea.setVisibility(View.VISIBLE);
//get user input
String userInput = inputTxt.getText().toString(); // show this string in a new row of listview
//BUT how to dynamically add new row to the listview here???
}
});
But I am not sure how to add new row to the listview programmatically, anyone can help me?
By the way, I have another layout xml fiel (row.xml) which defined each row's layout.
-----------------------UPDATE------------------------------------
Each row of the list contain a icon and a text string. My list adapter and row layout are showing below:
My adapter:
private static class MyListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
ArrayList<String> arraylist;
public MyListAdapter(Context context, ArrayList<String> arraylist) {
mInflater = LayoutInflater.from(context);
this.arraylist = arraylist;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
holder.userInput = (TextView) convertView.findViewById(R.id.user_input);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.icon.setImage(???);
holder.userInput.setText(arraylist.get(position));
return convertView;
}
static class ViewHolder {
ImageView icon;
TextView userInput;
}
}
my list row layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
>
<ImageView
android: id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/user_input"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textSize="10dip"/>
</LinearLayout>
Make a Global variable as below
ArrayList<String> arraylist = new ArrayList<String>();
On Click of send button update the adapter that you are setting on ListView by adding
String userInput = inputTxt.getText().toString();
arraylist.add(userInput)
in adapter and then call
adapter.notifyDataSetChanged();
Update
I updated answer in your question and in this post copy your new Adapter class and use that