Reputation: 2728
I have a ListView
whose each element is a custom layout. The layout consist of two frames: first one is just a TextView
, second one is a LinearLayout
consist of two images. What I am trying to do is, if i click an element of ListView
, if the LinearLayout
is "gone", it gets "visible" and TextView
gets disable. If LinearLayout
is "visible", it gets "gone" and TextView
gets disable. Here is my following code:
Code:
ListView lvw = (ListView) layout.findViewById(R.id.formats);
formatAdapter adapter = new formatAdapter(act, arr); //act is context and arr is an array of String
lvw.setAdapter(adapter);
lvw.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
TextView tev = (TextView) arg1
.findViewById(R.id.formatN);
LinearLayout extraB = (LinearLayout) arg1
.findViewById(R.id.extraButtons);
if (extraB.getVisibility() == View.GONE) {
extraB.setVisibility(View.VISIBLE);
tev.setEnabled(false);
} else {
extraB.setVisibility(View.GONE);
tev.setEnabled(true);
}
}
});
formatAdapter.java
public class formatAdapter extends BaseAdapter {
LayoutInflater Inflater;
Context con;
String[] names;
public formatAdapter(Context c, String[] s) {
con = c;
names = s;
Inflater = (LayoutInflater) con
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return names.length;
}
@Override
public Object getItem(int arg0) {
return null;
}
@Override
public long getItemId(int arg0) {
return 0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
View v1 = arg1;
v1 = Inflater.inflate(R.layout.adapter_formats, null);
TextView tv = (TextView) v1.findViewById(R.id.formatN);
tv.setText(names[arg0]);
return v1;
}
}
adapter_formats.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/formatN"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp" />
<LinearLayout
android:id="@+id/extraButtons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"
android:visibility="gone">
<ImageView
android:id="@+id/play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/cD"
android:src="@drawable/img_29" />
<View
android:layout_width="50dp"
android:layout_height="0dp"
android:contentDescription="@string/cD" />
<ImageView
android:id="@+id/download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/img_31" />
</LinearLayout>
</FrameLayout>
Now, I want that if for any element, the LinearLayout
is visible, and if I click on some other element, that elements LinearLayout
gets gone and TextView
gets enable(default layout). Let me explain with example: If I cliked the first element, its LinearLayout
gets visible. I want that if I click on 2nd element, the linear layout of first element gets gone automatically. I tried to explain well but sorry if I was unable to explain good. Can anyone help me with this?
Upvotes: 4
Views: 277
Reputation: 1967
The trick here is to keep hold of the selected position so that you know which view you need to modify when the next list item is clicked.
You can take a class-level variable that will hold the current selected position
private int mCurrentPosition = -1;
and you can replace your ListView
s onItemClick()
method with the below code.
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
TextView tev = (TextView) arg1.findViewById(R.id.formatN);
LinearLayout extraB = (LinearLayout) arg1
.findViewById(R.id.extraButtons);
if (mCurrentPosition > -1) {
View v = arg0.getChildAt(mCurrentPosition);
v.findViewById(R.id.extraButtons).setVisibility(View.GONE);
}
if (extraB.getVisibility() == View.GONE) {
extraB.setVisibility(View.VISIBLE);
tev.setEnabled(false);
} else {
extraB.setVisibility(View.GONE);
tev.setEnabled(true);
}
mCurrentPosition = arg2;
}
This should definately solve your problem. Happy Coding :)
Upvotes: 1
Reputation: 51571
In your adapter, hold the position
for which the LinearLayout should be visible:
public class formatAdapter extends BaseAdapter {
LayoutInflater Inflater;
Context con;
String[] names;
// Position to show
private int positionToShow;
// Constants
// Default - All LinearLayouts are hidden
final static int NO_CURRENT_SELECTION = -1
public formatAdapter(Context c, String[] s) {
con = c;
names = s;
Inflater = (LayoutInflater) con
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Initial setting
positionToShow = NO_CURRENT_SELECTION;
}
// Updates 'positionToShow' - used in ListView's OnItemClickListener
public void setPositionToShow(int newPosition) {
positionToShow = newPosition;
}
// Current position for which the LinearLayout should be visible
public int getPositionToShow() {
return positionToShow;
}
}
In your ListView's OnItemClickListener, update positionToShow
using the setPositionToShow()
method we defined above:
lvw.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// User has clicked the same position again - toggle visibility
if (yourAdapter.getPositionToShow() == arg2) {
// No LinearLayouts should be visible
yourAdapter.setPositionToShow(
FormatAdapter.NO_CURRENT_SELECTION);
} else { // User has clicked a new position
// Show LinearLayout for this position
yourAdapter.setPositionToShow(arg2);
}
// Refresh the ListView
yourAdapter.notifyDataSetChanged();
}
});
Finally, in your adapter's getView(...)
method, use positionToShow
to manage visibility of views:
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
View v1 = arg1;
v1 = Inflater.inflate(R.layout.adapter_formats, null);
TextView tv = (TextView) v1.findViewById(R.id.formatN);
// Initialize the LinearLayout
LinearLayout ll = (LinearLayout) v1.findViewById(R.id.extraButtons);
tv.setText(names[arg0]);
// This position's LinearLayout should be visible
if (positionToShow == arg0) {
ll.setVisibility(View.VISIBLE);
tv.setEnabled(false);
} else { // Either the position is not in view,
// or 'positionToShow' is set to NO_CURRENT_SELECTION
ll.setVisibility(View.GONE);
tv.setEnabled(true);
}
return v1;
}
Upvotes: 1
Reputation: 2728
Just found a way to do this and I feel awesome :) though this way is not genuine :P To hide the views of other lists, I took a view globally in my class and initialize it to null(the view is same class which I want to hide, for example, here I want to make the linear layout of previous list element to gone, so i took a global linear layout). Then inside each onItemClickListener, I put the following code at beginning:
if(myGlobalView!=null)
{
myGlobalView.hide();
}
Also, when I make the view of other list element visible, I assign that view to my global view by following code:
myGlobalView = myCurrentView;
Hope it help other people :)
Upvotes: 1