Cannot change the visiblity of an ImageView - android

I have a ListView using a custom cursoradapter to fill the ListView.
The row.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" >
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="fill_parent">
<TextView
android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:gravity="center_vertical"
android:ellipsize="marquee"
android:textSize="24dp" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/artist"
android:singleLine="true"
android:ellipsize="marquee"
android:textSize="14dp" />
</LinearLayout>
<ImageView
android:id="#+id/currentplaying"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginLeft="1dip"
android:src="#android:drawable/ic_media_play"
android:contentDescription="#string/now_playing"
android:visibility="gone" />
</LinearLayout>
As you can see, the ImageView's visibility is gone. I want to make it
visible for one particular row. Here is the code I tried but it is not
working...
View view = getListView().getAdapter().getView(0, null, null);
ImageView iv = (ImageView)view.findViewById(R.id.currentplaying);
iv.setVisibility(ImageView.VISIBLE);
Thanks in advance.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.yourlayout, null);
holder.imgViewLogo = (ImageView) convertView.findViewById(R.id.imgViewLogo);
convertView.setTag(holder);
}
else {
holder=(ViewHolder)convertView.getTag();
}
if(position==0) {
holder.imgViewLogo.setVisiblity(View.VISIBLE);
}
return convertView;
}
EDIT:
I got it working. I used this to start the ListView activity.
intent.putExtra("id", c.getInt(c.getColumnIndex(DatabaseHelper._ID)));
startActivity(intent);
In the ListView activity,
currentplayingid = getIntent().getExtras().getInt("id");
Then I added this in bindview()
ImageView imgview = (ImageView)view.findViewById(R.id.currentplaying);
int id = c.getInt(c.getColumnIndex(DatabaseHelper._ID));
if (id == SongsListActivity.this.currentplayingid)
imgview.setVisibility(View.VISIBLE);
else
imgview.setVisibility(View.GONE);

I got it working. I used this to start the list view activity.
intent.putExtra("id", c.getInt(c.getColumnIndex(DatabaseHelper._ID)));
startActivity(intent);
In the listview activity,
currentplayingid = getIntent().getExtras().getInt("id");
Then i added this in bindview()
ImageView imgview = (ImageView)view.findViewById(R.id.currentplaying);
int id = c.getInt(c.getColumnIndex(DatabaseHelper._ID));
if ( id == SongsListActivity.this.currentplayingid )
imgview.setVisibility(View.VISIBLE);
else
imgview.setVisibility(View.GONE);

perhaps you should do it in getView() of your adapter
EDIT:
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
// codes...
if (position == 0)
{
holder.imgViewLogo.setVisibility(ImageView.VISIBLE);
}
else
{
holder.imgViewLogo.setVisibility(ImageView.GONE);
}
// codes...
}

You have to do it like this
iv.setVisibility(View.VISIBLE);

If it is working some time then may be i can help you. What happen that whenever you move you listview it recreates all views again in this case it never save the last state of view. So what you need to do is to save state of your each imageview and in getView() you have to set accordingly.I am posting one of my answer it may help you.
Here is a little code for your help: I will create a boolean arraylist.
private ArrayList imageview_visible = null;
Then I will set states of all imageview as false in my constructor:
for (int i=0; i < no_of_elements.size(); i++) {
imageview_visible.add(i, false);
}
In your getView write this code:
public View getView (int position, View convertView, ViewGroup parent)
{
//WRITE YOUR CODE
if (imageview_visible.get(position) == true)
{
//SET YOUR IMAGE VIEW AS VISIBLE
} else {
// SET IMAGEVIEW AS GONE
}
}
Whenever you unhide or hide your view just save it into imageview_visible.set(true or false) this will save state of you all imageview and set every image view accordingly

Use LayoutInflater to get view object
LayoutInflater inflater = this.getLayoutInflater();
View rowView = inflater.inflate(R.layout.row, null, true);
ImageView iv = (ImageView)view.findViewById(R.id.currentplaying);
iv.setVisibility(ImageView.VISIBLE);

Try the following code as follows,
private class ViewHolder
{
ImageView imgViewLogo;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if(convertView==null)
{
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.yourlayout, null);
holder.imgViewLogo = (ImageView) convertView.findViewById(R.id.imgViewLogo);
convertView.setTag(holder);
}
else
{
holder=(ViewHolder)convertView.getTag();
}
if(position==0)
{
holder.imgViewLogo.setVisiblity(View.VISIBLE);
}
return convertView;
}
It Works for me...It may help you.

I ran into similar problems where several widgets would appear for some rows but not for others. The problems were due to view recycling. I'm not exactly sure if that's your issue here, but you should handle it anyway. The trick is to set visibility for every row; instead of just for the row that you want to appear/disappear.
So:
if (position == 0)
{
iv.setVisibility(ImageView.VISIBLE);
}
else
{
iv.setVisibility(ImageView.GONE);
}
Otherwise, you're assuming that for positions other than 0 the visibility is GONE but that might not be the case with view recycling. I do this work in bindView, by the way. Not sure if that's technically correct.

I have the same issue... i solved with a non standar solution, but worked for me...
v.setImageResource(R.color.transparent);
importing R from android
import android.R;

Both iv.setVisibility(View.VISIBLE); and iv.setVisibility(ImageView.VISIBLE); are correcte but It's better to use View instead of ImageView because VISIBLE & GONE are defined in View class.
You most change Both Visibility (VISIBLE or GONE) in that if. like:
if(?)
iv.setVisibility(View.VISIBLE);
else iv.setVisibility(View.GONE);

You can hide or show views using setVisibility(int) .
use iv.setVisibility(View.VISIBLE);

Related

How to make 1st item focus in ListView by default whenever enter the list View screen?

In my list View ,i have to make 1st item to be focused.In my app i have done D-PAD implementation,If i found the initial focus ,i will navigate the focus by using D-PAD.
i tried with setSelection(position) this code is not working.
I found some strange behaviour of listview,by default it always focus -1 position.I dont know why?,please clarify this behaviour.
My list view items are get load from server.So,when i have to make setSelection() and how to check the setAdpter task completed or not?.
#Override
public final View getView(final int position, final View convertView, final ViewGroup parent) {
final LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.list_item_faq, parent,
false);
final TextView textView = (TextView) rowView
.findViewById(R.id.faqlist_text);
textView.setText("text");
textView.setMaxLines(2);
textView.setEllipsize(android.text.TextUtils.TruncateAt.END);
return rowView;
}
adapter.xml
<?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="wrap_content"
android:background="#drawable/sel_list_item" //this is selector
android:gravity="center_vertical"
android:orientation="horizontal" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:layout_margin="2dp"
android:layout_gravity="center"
android:src="#drawable/cc_question_mark" />
<TextView
android:id="#+id/faqlist_text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginLeft="20dp"
android:gravity="center_vertical"
android:textColor="#6f6f6f"
android:textSize="22sp" />
</LinearLayout>
Please suggest any idea to make 1st item Focus.
Is your yourListView focusable?
Do in onResume()
yourListView.postDelayed(new Runnable() {
#Override
public void run() {
yourListView.setSelection(0);
yourListView.getChildAt(0).requestFocus()
}
}, 500);
Try doing the following:
public void onStart() {
super.onStart();
onListItemClick(listView, findViewById(android.R.id.content), 1, 0);
}
public void setActivateOnItemClick(boolean activateOnItemClick) {
listView.setChoiceMode(activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
You might need to give a little bit of delay before using set selection.
listView.postDelayed(new Runnable() {
#Override
public void run() {
listView.setSelection(0);
}
}, 500);
Try this
listView.getAdapter().getView(position, null, null).performClick();
if you already try list.setSelection(position) then try
list.setItemChecked(0, true);
I hope it works for you. but remember, update this in main thread or ui thread
UPDATE
also try this
list.setFocusable(true);
list.requestFocus();
UPDATE 1
When u get all list from data then call
adapter.notifyDataSetChanged();
list.setSelection(position);
Could you show me code getview method in Adapter?
I think you set static viewholder in Adapter.
You should delete if(convertView == null) condition.
Look like:
// if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(
R.layout.baseadapter_dropdown_layout, null);
holder.img = (ImageView) convertView.findViewById(R.id.imageView1);
convertView.setTag(R.layout.baseadapter_dropdown_layout, holder);
// } else {
// holder = (ViewHolder) convertView
// .getTag(R.layout.baseadapter_dropdown_layout);
// }
In the onResume() go for
mListView.setSelection(position);
or
mListView.setSelection(listview.getAdapter().getCount()-1);
also
mListView.requestFocus();
also try to manage null check before entering hard coded positions.
Use performItemClick. It will call the OnItemClickListener, if it is defined. This works in charm for me.
int setPosition = 0; // Your default position. Any value less than your list size.
int ignoreId = 0; // We ignore the row id of the item that was clicked.
yourListView.setItemChecked(setPosition, true);
yourListView.performItemClick(yourListView.getSelectedView(), setPosition, ignoreId);
There is no need to use post with listview you can simply use listView.setSelection(0) after adding the data into the list

ListView not scroll smoothly

I have a list view in which i have inflating 3 different type of view, and one type of that view contain horizontal scroll view.
Inside horizontal scroll view i have linear layout,in which i am inflating my custom xml.
All of this working, but scroll of parent list view is not smooth.
When i comment my horizontal scroll view code then list is scrolling smoothly.
Below is my code :
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
view = convertView;
int type = getItemViewType(position);
if(view == null){
mHolder = new ViewHolder();
if (type == 0) {
mHolder.mainLinearType1 = (LinearLayout) view.findViewById(R.id.main_linear);
mHolder.hsv1 = (HorizontalScrollView) view.findViewById(R.id.hsv);
}
if (type == 1) {
....
}
if (type == 2) {
....
}
view.setTag(mHolder);
}
else{
mHolder = (ViewHolder) view.getTag();
}
if(type==0){
mHolder.mainLinearType1.removeAllViews();
for (int i = 0; i <mList.get(position).getEventList().size(); i++) {
View additionView = mLayoutInflater.inflate(R.layout.activity_type1_subitem_view, null,false);
FrameLayout innerLinnerLayout=(FrameLayout)additionView.findViewById(R.id.frame_view);
ImageView activityImage = (ImageView) additionView.findViewById(R.id.activity_iv);
ProgressBar pb = (ProgressBar) additionView.findViewById(R.id.progress);
AQueryImageDownloader.loadImage(activityImage, pb, mList.get(position).getEventList().get(i).getEventImagePath(), mContext);
mHolder.mainLinearType1.addView(innerLinnerLayout);
}
}
I have try a lot but not able to make scrolling properly.
I have also try view pager and horizontal listView. But same issue is occur.
Please help in solve this issue.
Thanks in advance.
EDITED
Below is my listview inside xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container_ll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/White">
<include
android:id="#+id/header_view"
layout="#layout/header_layout" />
<ListView
android:id="#+id/list_view"
android:layout_below="#+id/header_view"
android:scrollbars="none"
android:visibility="gone"
android:divider="#color/LtGreen"
android:dividerHeight="1dp"
android:smoothScrollbar="true"
android:scrollingCache="false"
android:animationCache="false"
android:cacheColorHint="#android:color/transparent"
android:listSelector="#android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Check this :
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
This basically tells you to use an ASyncTask to handle the scrolling.
According to your implementation, you are always inflating the horizontal scrollview for each item, regardless of whether it is a recycled one, so every time Android needs to display an item, it needs to reinflating the horizontal scrollview again, which may explain why the scrolling is not smooth.
You can try to make a ListView as part of your item view. This ListView will be inflated once when your convertView == null, and everytime getView(position, ...) of the parent ListView is called you refresh the item's ListView Adapter with values of mList.get(position).getEventList(). Since we only swap data of a recycled view, my guess is that it will not affect scrolling much.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
view = convertView;
int type = getItemViewType(position);
if (view == null) {
mHolder = new ViewHolder();
if (type == 0) {
mHolder.mainLinearType1 = (LinearLayout) view.findViewById(R.id.main_linear);
mHolder.hsv1 = (HorizontalScrollView) view.findViewById(R.id.hsv);
mHolder.listView = (ListView) view.findViewById(R.id.frame_view); // assume this is your ListView
}
if (type == 1) {
....
}
if (type == 2) {
....
}
view.setTag(mHolder);
} else {
mHolder = (ViewHolder) view.getTag();
}
if (type==0) {
mHolder.mainLinearType1.removeAllViews();
mHolder.listView.setAdapter(new Adapter() {
// override adapter with implementation that returns items from mList.get(position).getEventList()
});
}
}

Android fragment + custom listview

Its my first post here but i am reading this Q&A for years and I always find an answer, but this time i cannot find it, or i cannot combine multiple answers with my problem. I hope you can help.
So I have fragment which overrides onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
db = new WineryDatabaseAdapter(getActivity());
bacveList = db.getBacve();
v = inflater.inflate(R.layout.sve_bacve, container, false);
Log.v("onCreateView", "oncreateview");
return v;
}
Then I have method where I set my data
public void getBacveItems(){
ArrayAdapter<Bacve> ad = new BacveListAdapter(getActivity(), bacveList);
lv = (ListView) v.findViewById(R.id.listSveBacve);
lv.setAdapter(ad);
lv.setOnItemClickListener(this);
Log.v("getBacveItems", "getBacveItems");
}
In that method I am calling my Adapter so i can use my listview layout
public class BacveListAdapter extends ArrayAdapter<Bacve>{
List<Bacve> bacve;
Context c;
String[] values = new String[] { "prva","druga" };
public BacveListAdapter(Context c,List<Bacve> l){
//super(c,R.layout.sve_bacve_item,l);
super(c,R.layout.sve_bacve_item,l);
Log.v("BacveListAdapter", "BacveListAdapter");
this.bacve = l;
this.c = c;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View iv = convertView;
TextView tv;
if (iv == null){
iv = (View)((LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.sve_bacve,parent,false);
tv = new TextView(c);
}
else{
Bacve bacva = bacve.get(position);
tv = (TextView) iv.findViewById(R.id.textNazivBacve);
tv.setText(bacva.getIme());
}
return iv;
}
}
But for some reason i am getting errors when trying to access tv. It is always null.
I think its something with views that are created/getted, and I am creating/getting some parent view in higher hierarchy. I have tried to debug it but dont know how to use those IDs in debug mode. Well not how to use it, but how to compare it so I can see is it right view.
Please help :)
I did it like this in this edit but nothing. Is it because i am using swipe views and I am getting wrong view in the first?
This is my sve_bacve_item and it has textview.
I am kind 1 step forward with #Raghunandan solution but now I have problem with convertin String to holder. I am trying to resolve that.
<?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">
<TextView
android:id="#+id/textNazivBacve"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:layout_toRightOf="#+id/bacveIcon"
android:text="#string/BacveNaziv"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ImageView
android:id="#+id/bacveIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignTop="#+id/textNazivBacve"
android:adjustViewBounds="true"
android:contentDescription="#string/Bacve"
android:maxHeight="120dp"
android:maxWidth="120dp"
android:src="#drawable/bacve_item" />
</RelativeLayout>
BR
Use a ViewHolder for perofrmance.
public static ViewHolder
{
TextView tv;
}
Change to
LayoutInflater mInflater;
public BacveListAdapter(Context c,List<Bacve> l){
//super(c,R.layout.sve_bacve_item,l);
super(c,R.layout.sve_bacve_item,l);
mInflater = LayoutInflater.from(c);
this.bacve = l;
this.c = c;
}
Change getView to
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null){
convertView = (View) mInflater.inflate(R.layout.sve_bacve,parent,false);
holder = new ViewHolder();
holder.tv = (TextView) convertView.findViewById(R.id.textNazivBacve);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
Bacve bacva = bacve.get(position);
holder.tv.setText(bacva.getIme());
return convertView;
}
Also you mention
This is my sve_bacve_item and it has textview
So change
convertView = (View) mInflater.inflate(R.layout.sve_bacve,parent,false);
to
convertView = (View) mInflater.inflate(R.layout.sve_bacve_item,parent,false);
Edit:
Your NPE was because you inflated the wrong layout. I got confused the first time.
Also you have commented this
public BacveListAdapter(Context c,List<Bacve> l){
//super(c,R.layout.sve_bacve_item,l);
remove the comment
public BacveListAdapter(Context c,List<Bacve> l){
super(c,R.layout.sve_bacve_item,l);
And do check this to understand ViewHolder pattern to understand why you need it.
A ViewHolder object stores each of the component views inside the tag
field of the Layout, so you can immediately access them without the
need to look them up repeatedly.
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
and also check
How ListView's recycling mechanism works
I'm guessing your layout doesn't have the TextView defined because your code should look like the following:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = (View)((LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.sve_bacve_item,parent,false);
}
TextView tv = (TextView)convertView.findViewById(R.id.textNazivBacve);
Bacve bacva = bacve.get(position);
tv.setText(bacva.getIme());
return iv;
}
And your custom layout should have a text view defined somewhere in your layout file like so.
<TextView android:id="#+id/textNazivBacve"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a TextView" />
UPDATE
Ok it looks like your layout file looks fine. You still do not need to create a TextView the way you were trying. You can simply findView. One thing I noticed, your inflate call is using the wrong layout (sve_bacve not sve_bacve_item), that is why it is unable to find the text view.
This line:
convertView = (View) mInflater.inflate(R.layout.sve_bacve,parent,false);
Should be:
convertView = (View) mInflater.inflate(R.layout.sve_bacve_item,parent,false);

OnItemClickListener Not Triggered on Android GridView

I have a Gridview filled by an Adapter which returns LinearLayouts each contains an ImageButton and TextView.
In the adapter I am binding an onClick and onLongClick event to the ImageButton.
I am trying to bind OnItemClickListener to the gridview but I don't know why that the onItemclicked never fired up.
It's my 6th hour without anything.
By the way;
OnItemSelectListener working perfectly on the Grid.
I am checking if some piece of code accidentally handles the onItemClicked but couldn't catch yet.
I need help guys.
gridView = (GridView) layoutInflater.inflate(R.layout.gridview, null);
gridView.setOnItemClickListener(new ItemClickListener());
.
.
.
//inner handler class
class ItemClickListener implements AdapterView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(mainActivity.getApplicationContext(),view + " clicked at pos " +
i,Toast.LENGTH_SHORT).show();
}
}
Do not use clickable objects in the grid. In that case Android cannot handle the click event of GridView.
Instead, use something to show a similar user interface view. Then handle that object's click actions.
Don't: put Button in the GridView to perform some click actions.
Do: put an ImageView instead of ImageButton and handle ImageView's click events.
If you wants to use Button or ImageButton then you need to write these attributes in your xml code of the widgets.
android:focusable="false"
android:focusableInTouchMode="false"
Its works for me.
But in GridView, Try to avoid use of these widgets. You can use any other widgets in place of these (Like ImageView or any other).
Also make sure, that your ListAdpter returns true for
public boolean isEnabled(int _position)
for the position you want to click.
Hey guyz finally got a solution...
what we were doing is directly accessing the Layout inside the GridView, so the onItemClickListener finds it confusing to access the item.
So the solution is to apply the onClickListener inside the Adapter (i.e. normally ArrayAdapter)
so what i m trying to say is:
public View getView(int position, View convertView, ViewGroup parent) {
//Here row is a view and we can set OnClickListener on this
final View row;
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
//Here we inflate the layout to view (linear in my case)
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.imageTitle = (TextView) row.findViewById(R.id.text);
holder.image = (ImageView) row.findViewById(R.id.image);
row.setTag(holder);
} else {
row = convertView;
holder = (ViewHolder) row.getTag();
}
ImageItem item = data.get(position);
holder.imageTitle.setText(item.getTitle());
holder.image.setImageBitmap(item.getImage());
//Now get the id or whatever needed
row.setId(position);
// Now set the onClickListener
row.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(context, "Clicked" + row.getId() + "!!",
Toast.LENGTH_SHORT).show();
}
});
return row;
}
Try to set
android:clickable="false"
android:focusable="false"
I meet same problem too, because of several reasons.
So, here's my tips:
Extend BaseAdapter for your adapter;
Use OnClickListener inside the getView in adapter instead setting OnItemClickListener for GridView;
Avoid setting LayoutParams multiple times;
Check if position = 0, don't use convertView, inflate new View;
Set OnClickListener not only for parent View, but for any child View, if any;
Make all your Views clickable.
I just tested it on 4 devices, and this solution works as expected. Hope, it will help in your case.
Correct me, if I made something wrong.
Layout code XML:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#273238"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:padding="1dp">
<ImageView
android:id="#+id/open_image_item_imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/loh"
android:clickable="true"
android:focusable="false"
android:focusableInTouchMode="false"
android:scaleType="centerCrop"/>
<TextView
android:id="#+id/open_image_item_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_gravity="bottom"
android:padding="4dp"
android:textSize="10sp"
android:ellipsize="start"
android:background="#55000000"
android:textColor="#FFFFFF"
android:text="image name"/>
</FrameLayout>
Adapter code Java:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if(convertView != null && position != 0)
view = convertView;
else{
view = LayoutInflater.from(getContext()).inflate(R.layout.open_image_item_layout, null, false);
view.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, size));
}
TextView textView = (TextView)view.findViewById(R.id.open_image_item_textview);
ImageView imageView = (ImageView)view.findViewById(R.id.open_image_item_imageview);
...
View.OnClickListener onClickListener = getOnClickListener(files[position]);
view.setOnClickListener(onClickListener);
textView.setOnClickListener(onClickListener);
imageView.setOnClickListener(onClickListener);
return view;
}

Android: How to hide a ListView Item

How can you hide an item in a ListView or at least set its height to zero?
I have tried setting the visibility of the View to GONE but it still maintains the item's space (height).
Ressurecting an old question, but I just had this issue where I wanted to hide list items temporarily based upon criteria outside of the list data. What I ended up doing was creating a "null item" layout in xml and returned that based upon my criteria instead of the convert view in getView()...
instead of returning the convertView, I returned my null_item...
return inflater.inflate(R.layout.null_item, null);
null_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</LinearLayout>
if you want to hide the item like this:
convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,1));
convertView.setVisibility(View.GONE);
can't be AbsListView.LayoutParams(-1,0);
if convertview are reused you should add this below to set it height back:
if(convertView.getVisibility() == View.GONE) {
convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
convertView.setVisibility(View.VISIBLE);
}
When it comes to ListView, to make it efficient, we use ViewHolder pattern. The way to use ViewHolder Pattern and R.layout.row_null of the following xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</LinearLayout>
is to use with getViewTypeCount() and getItemViewType(int position) as follow.
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int position) {
return (hideStatusCheck(position)) ? 1 : 0;
}
#Override
public View getView(int pos, View convertView, ViewGroup parent) {
View rowView = convertView;
if (hideStatusCheck(pos)) {
if (rowView == null || rowView.getTag() != null) {
LayoutInflater inflater = mActivity.getLayoutInflater();
rowView = inflater.inflate(R.layout.row_null, parent, false);
}
} else {
if (rowView == null) {
rowView = inflateNormalView(parent);
} else if (rowView.getTag() == null) {
rowView = inflateNormalView(parent);
} else {
ViewHolder holderToCheck = (ViewHolder) rowView.getTag();
Integer storedPos = (Integer) holderToCheck.getTag(POSITION);
if (storedPos == null || storedPos != pos)
rowView = inflateNormalView(parent);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
holder.setTag(POSITION,pos);
/*
Populate data
*/
return rowView;
}
private View inflateNormalView(ViewGroup parent) {
View rowView;
LayoutInflater inflater = mActivity.getLayoutInflater();
rowView = inflater.inflate(R.layout.normal_item, parent, false);
ViewHolder viewHolder = new ViewHolder();
assert rowView != null;
/* Initiate normal findViewById thing*/
rowView.setTag(viewHolder);
return rowView;
}
We do the checking of the item's View type and if it meets the hide check, it will return 1, otherwise 0. The ListView knows that there will be 2 types of View from getViewTypeCount. Now, the getView will return the approriate View depending on the hideStatusCheck. To make a robust ListView, we want to use the ViewHolder pattern. We don't need to use ViewHolder when it is hidden. We simply inflate the R.layout.row_null and return it. We will use the ViewHolder for the R.layout.normal_item. Here is the tricky part assuming the hiding check is not static. The first check of rowView==null is standard. The second check of rowView.getTag()==null is to see if the View is coming back to normal
from hiding. The third check in the last else clause is to check if the ViewHolder retained in the tag is the right ViewHolder. If these conditions are met, we always inflate the view again. Yes, it is true that, the ViewHolder pattern is not used throughout but it uses to certain extends. It is better than nothing.
I did some tinkering with a drag and drop list from here. When an item is popped out of the list to be moved around the cell space it occupied has it's height set to 1px (see line 238) so it appears "gone". I couldn't find a way to handle this better as setting height to 0 fails as does visibility GONE.
That said, If you really want to get rid of a row less temporarily, it might be a good idea to change the backing of the Adapter and call notifyDataSetChanged() on it.
I have look at source code. And there is only one way to hide item without notifyDataSetChanged(). You must set visibility GONE for all inner views and remove background image and paddings for item's view.
Note: Row with such invisible element will be selectable.
P.S: This is very usefull for ExpandableListView if you want to hide group view it self.
add to your ListView object:
android:dividerHeight="0px"
android:divider="#FFFFFF"
Divider color doesn't matter
only setting dividerHeight doesn't work
This does remove the divider though...
I think I have a much easier / safer solution: you just have to "embed" your item in a Layout, and change the visibility of this parent layout.
<?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="wrap_content"
android:orientation="horizontal" >
<!-- Embed ListView Item into a "parent" Layout -->
<LinearLayout
android:id="#+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<!-- This is the normal content of your ListView Item -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="World" />
</LinearLayout>
</LinearLayout>
Then in your code just do:
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
LayoutInflater li = mActivity.getLayoutInflater();
view = li.inflate(R.layout.my_listview_item, null);
}
LinearLayout parentLayout = (LinearLayout) view.findViewById(R.id.parentLayout);
if (shouldDisplayItem(position)) {
parentLayout.setVisibility(View.VISIBLE);
} else {
parentLayout.setVisibility(View.GONE);
}
return view;
}
This way you always use/reuse the same item, and just hide/show it.
To Hide whole raw from listview in android:-
RelativeLayout parentLayout = (RelativeLayout) view.findViewById(R.id.relative);
if (productPojoList.get(position).getSERSERVICETYPE().toString().equals("Group|Promotional")){
view.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,1));
view.setVisibility(View.GONE);
} else {
if(view.getVisibility() == View.GONE) {
view.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
view.setVisibility(View.VISIBLE);
}
}

Categories

Resources