berserk
berserk

Reputation: 2728

Accessing views of other element of ListView from some element

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

Answers (3)

d3m0li5h3r
d3m0li5h3r

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 ListViews 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

Vikram
Vikram

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

berserk
berserk

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

Related Questions