I'm trying to set a fixed progress on items in a ListView. I only see an indeterminate spinning circle in the ListView.... what am I doing wrong? (I'm sure the answer is simple... I'm just not seeing it)
For the following adapter layout xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="#+id/some_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ProgressBar
android:id="#+id/some_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
Code:
public class SomeListAdapter extends ArrayAdapter<MyItem> {
private static class ViewHolder {
TextView nameTextView;
ProgressBar valueProgressBar;
}
public BestChoiceListAdapter(Context context, List<MyItem> items) {
super(context, R.layout.list_item, items);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View view = convertView;
if (view == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.nameTextView = (TextView) view.findViewById(R.id.some_text);
holder.valueProgressBar = (ProgressBar) view.findViewById(R.id.some_progress);
view.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
MyItem optionItem = getItem(position);
holder.nameTextView.setText(optionItem.getOptionName());
int progress = (int) (optionItem.getOptionValue());
holder.valueProgressBar.setProgress(progress);
return view;
}
}
The simplest way is to apply the horizontal style to it:
<ProgressBar
android:id="#+id/some_progress"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
This will set up all the attributes you will otherwise need to add manually to apply a determinate progress mode.
If you're curious, this is what that system style looks like, in case you wanted to apply the properties individually:
<style name="Widget.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">#android:drawable/progress_horizontal</item>
<item name="android:indeterminateDrawable">#android:drawable/progress_indeterminate_horizontal</item>
<item name="android:minHeight">20dip</item>
<item name="android:maxHeight">20dip</item>
</style>
HTH
Change the indeterminate mode to false!
<ProgressBar
android:id="#+id/some_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
/>
Related
I was searching how to change groupview's background as it expands/collapse. I didn't found my answer, but I solved by simple doing this:
BaseExpandableListAdapter:
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ViewHolderGroup holder;
if ( convertView == null ){
convertView = inflater.inflate(R.layout.home_cell, null);
holder = new ViewHolderGroup();
convertView.setTag(holder);
holder.tvNome = (TextView) convertView.findViewById(R.id.cellNome);
holder.btCodigo = (ToggleButtonEbrimaBold) convertView.findViewById(R.id.btCodigo);
holder.tvLancadas = (TextView) convertView.findViewById(R.id.cellLancadas);
holder.layoutBackground = (LinearLayout) convertView.findViewById(R.id.layoutBackground);
}
else{
holder = (ViewHolderGroup) convertView.getTag();
}
holder.layoutBackground.setSelected(isExpanded);
return convertView;
}
ViewHolderGroup:
class ViewHolderGroup {
TextView tvNome;
ToggleButtonEbrimaBold btCodigo;
TextView tvLancadas;
LinearLayout layoutBackground;
LinearLayout layoutReceiver;
}
home_cell.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/layoutBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="100dp"
android:orientation="vertical"
android:gravity="center_vertical"
android:background="#drawable/disciplina_line">
... GroupView content ...
</LinearLayout>
</LinearLayout>
disciplina_line.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="false" android:drawable="#drawable/line_white"/>
<item android:state_selected="true" android:drawable="#drawable/line_selected"/>
</selector>
I wanted to share this alternative. Hope it helps !
In a fragment, I have a ListView that has a custom ParseQueryAdapter<T>. The problem may not have anything to do with Parse, although I'm not sure.
As I was testing my app, I noticed something very strange. When I would scroll down my ListView, all the visible ListView items would be drawn on top of the next ListView item as seen in the second image below.
The list initialized properly as such:
As you can see, in my list item layout, I have an ImageView (ParseImageView to be specific) and a TextView. The TextView now displays some notes (don't mind the ID user_name_text_view) and the ImageView displays a placeholder blank profile picture.
When I scrolled down, the list looked like:
Here's my list view layout named fragment_post_view_list_view:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/post_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Here's my list item layout named list_item_post_view:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.parse.ParseImageView
android:id="#+id/icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_alignParentLeft="true"
android:background="#drawable/com_facebook_profile_picture_blank_square" />
<TextView
android:id="#+id/user_name_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/icon"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/link_blue" />
</RelativeLayout>
Here's my adapter named PostViewListViewAdapter:
public class PostViewListViewAdapter extends ParseQueryAdapter<Post> {
// call superclass with a query to populate list view
public PostViewListViewAdapter(Context context, final String[] postsObjectIds) {
super(context, new ParseQueryAdapter.QueryFactory<Post>(){
public ParseQuery<Post> create() {
ParseQuery<Post> query = Post.getQuery();
query.whereContainedIn("objectId", Arrays.asList(postsObjectIds));
return query;
}
});
}
// this is similar to getView method in an adapter
#Override
public View getItemView(Post post, View v, ViewGroup parent) {
if(v == null) {
v = View.inflate(getContext(), R.layout.list_item_post_view, null);
}
super.getItemView(post, v, parent);
TextView usernameTextView = (TextView) v.findViewById(R.id.user_name_text_view);
usernameTextView.setText(post.getNotes()); // some string
return v;
}
}
How can I fix this problem?
Is this an issue with XML or Java?
I was following the two tutorials from Parse and the example from the Parse docs:
MealSpotting
Parse Query Adapter
I set the adapter and ListView here:
View rootView = inflater.inflate(R.layout.fragment_post_view_list_view, container, false);
mPostsObjectIds = SOME_STRING[];
PostViewListViewAdapter adapter = new PostViewListViewAdapter(getActivity(), mPostsObjectIds);
ListView listView = (ListView) rootView.findViewById(R.id.post_list_view);
listView.setAdapter(adapter);
I've tried getting rid of the ParseImageView in my list item layout, but my TextViews still draw on top of each other when I scroll.
Edit:
I forgot to mention that the list items display on top of each other after an orientation change.
I tested this on my Galaxy S5 (Android version 4.4.2 and Parse 1.4.1).
In my Activity, I show the Fragment here (called PostViewListViewFragment):
getSupportFragmentManager().beginTransaction().add(android.R.id.content, new PostViewListViewFragment()).commit();
Try below layout :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/post_list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none" >
</ListView>
</RelativeLayout >
Make Sure your adapter like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// reuse views
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.rowlayout, null);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) rowView.findViewById(R.id.TextView01);
rowView.setTag(viewHolder);
}
// fill data
ViewHolder holder = (ViewHolder) rowView.getTag();
String s = names[position];
holder.text.setText(s);
return rowView;
}
}
PS:You should watch this Google IO video about Listview,and here is the slides.
First create a ViewHolder class
static class ViewHolder {
protected TextView usernameTextView;
}
Then change your getItemView method like below
public View getItemView (Post post, View convertView , ViewGroup parent)
{
ViewHolder viewHolder = null;
if (convertView == null)
{
LayoutInflater inflator = context.getLayoutInflater();
convertView = inflator.inflate(R.layout.list_item_post_view, null);
viewHolder = new ViewHolder();
viewHolder.usernameTextView = (TextView)convertView.findViewById(R.id.user_name_text_view);
convertView.setTag(viewHolder);
convertView.setTag(R.id.user_name_text_view, viewHolder.usernameTextView);
}
else
{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.usernameTextView.setText(post.getNotes()); // some string
return convertView;
}
The problem seems to be in your list item layout -
Change it to this -
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.parse.ParseImageView
android:id="#+id/icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_alignParentLeft="true" />
<TextView
android:id="#+id/user_name_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/icon"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/link_blue" />
</RelativeLayout>
Probably you have extra background for each list item set that is causing such effect.
Alter and watch.
Hope this gives you idea!
Try changing your list view layout height to match_parent.
Credit to #VedPrakash for helping me fix this.
In case it helps anyone, I fixed the problem by replacing the fragment not adding it. So I changed this line from:
getSupportFragmentManager().beginTransaction().add(android.R.id.content, new PostViewListViewFragment()).commit();
to:
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, new PostViewListViewFragment()).commit();
I built a ListView with a Custom Adapter so that I have a Checkbox (invisible at the time) and a TextView to display some text.
Now I want to have the beautiful animation when selecting an item in the List (Background beeing blue for the time you touch the element). Is this possible?
I already added an OnLongTouchListener and it worked but no animation!
Would be cool to get some help :)
Layout-XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<CheckBox
android:id="#+id/list_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
android:visibility="gone"
android:text=""
android:focusable="false"
android:clickable="false">
</CheckBox>
<TextView
android:id="#+id/list_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text=""
android:clickable="true"
android:longClickable="true" >
</TextView>
</LinearLayout>
The Java-Code:
private class CommunityListAdapter extends ArrayAdapter<Community> {
private List<Community> items;
private Context context;
public CommunityListAdapter(Context context, List<Community> communities) {
super(context, R.layout.list_item, communities);
this.items = communities;
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_item, null);
}
Community item = items.get(position);
if(item != null) {
TextView textView = (TextView) view.findViewById(R.id.list_text);
if(textView != null) {
textView.setText(item.getName());
textView.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View view) {
startActionMode(new MultiChoiseCABListener());
Toast.makeText(context, "TEST", 10).show();
return false;
}
});
}
}
return view;
}
}
Create pressed state xml in your drawables in which you set different bitmaps to be displayed at different states of tap, and set that xml as your main layout background.
example state xml.
list_item_bg_state.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/blue_bg" />
<item android:drawable="#drawable/white_bg"/>
</selector>
where blue_bg and white_bg are two.png images in your drawables.
note above xml should be in your drawables folder. Now set this xml as background of your list item main layout. like,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/list_item_bg_state"
android:orientation="horizontal" >
</LinearLayout>
regards,
Aqif
You havent defined animation please define animation and associate with this view.
Animation a = new AlphaAnimation(1.00f, 0.00f);
a.setDuration(1000);
YOURTEXTVIEW.startAnimation(a);
I have a list item with a button inside.
When the button is shown, the list item is not clickable anymore.
To make it clickable again, I have replaced the button with a view. The problem is that, when the list item is clicked, the button changes background image (like if it is clicked). How can avoid this bad behaviour?
Thanks
Set the following properties for you button
android:focusable="false"
android:focusableInTouchMode="false"
For ImageButton, also add the following to the parent view
android:descendantFocusability="blocksDescendants"
Actually I have just found a wonderful explaination: http://android.cyrilmottier.com/?p=525
The problem and the solution is very well explained there.
The part of the link provided by #Matroska that answers the question:
You must add
android:descendantFocusability="blocksDescendants"
to the parent ViewGroup that defines the layout of an item of your ListView.
Note: this will no longer allow you to focus on the inner button with hardware buttons.
(sorry, I cannot comment yet)
You can try this:
yourButton.setFocusable(false);
yourButton.setFocusableInTouchMode(false);
Here is an example of a clickable button inside a ListView. If you want to download the project you can download the IntelliJ Gradle project from my web site:
http://developersfound.com/ListButtonClickExample.zip
The custom adapter in this example has the click listener instead of the listener being inside the Fragment or Activity. It's done is such a way that there is only on listener object and all button are bound to them for efficiency.
Here is the ListItem layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.jc_systems.listbuttonclickexample.app.ItemFragment">
<LinearLayout
android:id="#+id/test_container"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/image_list_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/exaple_icon"
android:layout_weight=".1"
android:layout_gravity="left|top"/>
<TextView
android:id="#+id/lbl_list_item"
android:layout_width="168dp"
android:layout_height="wrap_content"
android:text="I think this should take up two lines..."
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:gravity="center_vertical|center_horizontal"
android:layout_gravity="center_vertical"/>
<Button
android:id="#+id/cmd_list_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello"
android:layout_weight="0.2"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_gravity="right|top"/>
</LinearLayout>
</FrameLayout>
And here is the CustomAdapter:
import android.app.Activity;
import android.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
public class MyCustomAdapter extends ArrayAdapter {
private final ArrayList<FragmentItems> list;
private static Activity context;
private View.OnClickListener adaptrDynaListener = null;
public MyCustomAdapter(Activity context, ArrayList<FragmentItems> list) {
super(context, R.layout.fragment_items, list);
this.context = context;
this.list = list;
adaptrDynaListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
String buttonText = ((Button) v).getText().toString();
new AlertDialog.Builder(MyCustomAdapter.context).setTitle("Alert").setMessage(buttonText).setNeutralButton("OK", null).show();
}
};
}
static class ViewHolder {
protected ImageView image_list_image;
protected TextView lbl_list_item;
protected Button cmd_list_button;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
ViewHolder viewHolder = new ViewHolder();
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.fragment_items, null);
viewHolder.image_list_image = (ImageView) view.findViewById(R.id.image_list_image);
viewHolder.lbl_list_item = (TextView) view.findViewById(R.id.lbl_list_item);
viewHolder.cmd_list_button = (Button) view.findViewById(R.id.cmd_list_button);
viewHolder.cmd_list_button.setTag(viewHolder);
view.setTag(viewHolder);
}
else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.lbl_list_item.setText(list.get(position).getMessage());
holder.cmd_list_button.setText(list.get(position).getButtonText());
holder.cmd_list_button.setOnClickListener(adaptrDynaListener);
return view;
}//public View getView(int position, View convertView, ViewGroup parent)
public int getCount() {
if(list.size() <= 0) {
return 1;
}
return list.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
}
I've tested this Adapter pattern quite extensively and it seems very stable in ListView, ListActivities and ListFragments.
You can create an xml file that contains the clicked behavior of the view. Create an xml file, custom_button.xml (or whatever you want to call it) and fill it with this code:
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Focused -->
<item android:state_focused="true" android:state_pressed="false" android:color="#color/black"/>
<!-- Pressed -->
<item android:state_focused="false" android:state_pressed="true" android:color="#color/black"/>
<!-- Focused+Pressed -->
<item android:state_focused="true" android:state_pressed="true" android:color="#color/black"/>
<!-- Disabled -->
<item android:state_enabled="false" android:color="#color/dark_grey_text"/>
<!-- Default -->
<item android:color="#color/white"/>
</selector>
You can then change the
android:color=""
To
android:drawable=""
And assign them to any drawable resources you have in your drawable folder. Then in the xml file for your layout containing the view, add:
android:background="custom_button"
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();