Android ListView that does not scroll?
Asked Answered
D

4

16

I'm trying to make a layout that is something similar to how the android market is...where say under comments there is what appears to be a ListView but it does not scroll (the whole page scroll but not the comments). I'm not sure if its even a ListView but I want something that looks like the list view (ie. have those divider bars and what not but NOT SCROLLABLE). There are people suggesting to use a LinearLayout instead of a ListView but I also want the items to be clickable and open a new activity. Please help?

My current layout tree is like so

<LinearLayout>
  <ScrollView>
     <RelativeLayout>

I am looking to put content inside the RelativeLayout.

Demodena answered 7/7, 2010 at 7:4 Comment(1)
Now Support Library allows to make it easier with <NestedScrollView> and <RecyclerView>. NestedScrollView can contains any layout with number of simple or recycler- views insideAtheistic
G
30

As explained by the programmers that did the listView in this video from GoogleIo never put a ListView inside a scroll View. If your list should not scroll use a ViewGroup like a linear Layout and add all the items to this ViewGroup in a loop in your code. If you want a whole row to be clickable you have to use another ViewGroup as the root node for each row and add the OnClickListener to this View.

Sample Code:

LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

for (int current = 0; current < itemCount; current++) {
   View view = inflater.inflate(R.layout.layout_id, parent, false);

   //initialize the view

   view.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
          Intent intent = new Intent(getApplicationContext(), CLASS_TO_START)
          startActivity(intent);
      }
   });
   viewGroup.addView(view);
   if (current < itemCount - 1) {
      inflater.inflate(R.layout.line, viewGroup);
   }
}

This code will generate one View for every item that you have and put it into the viewGroup. After every item but the last it will also add a divider to the viewGroup.

Glottic answered 7/7, 2010 at 10:33 Comment(3)
thanks =) I ended up using this method after figuring out what an LayoutInflater was and how to use it...now I just have to prettify things in xml.Demodena
Quick question...how do I make the View highlight when I click it?Demodena
@Demodena I know this is an old post, but did you know how to highlight a child view after it has been clicked?Touraco
B
14

I had the same issue. I simply extended the default LinearLayout with a setAdapter method:

public class LinearListView extends LinearLayout
{
    Adapter adapter;
    Observer observer = new Observer(this);

    public LinearListView(Context context)
    {
        super(context);
    }

    public LinearListView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public LinearListView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    public void setAdapter(Adapter adapter)
    {
        if (this.adapter != null)
            this.adapter.unregisterDataSetObserver(observer);

        this.adapter = adapter;
        adapter.registerDataSetObserver(observer);
        observer.onChanged();
    }

    private class Observer extends DataSetObserver
    {
        LinearListView context;

        public Observer(LinearListView context)
        {
            this.context = context;
        }

        @Override
        public void onChanged()
        {
            List<View> oldViews = new ArrayList<View>(context.getChildCount());

            for (int i = 0; i < context.getChildCount(); i++)
                oldViews.add(context.getChildAt(i));

            Iterator<View> iter = oldViews.iterator();

            context.removeAllViews();

            for (int i = 0; i < context.adapter.getCount(); i++)
            {
                View convertView = iter.hasNext() ? iter.next() : null;
                context.addView(context.adapter.getView(i, convertView, context));
            }
            super.onChanged();
        }

        @Override
        public void onInvalidated()
        {
            context.removeAllViews();
            super.onInvalidated();
        }
    }
}

Hope this helps!

Baba answered 13/4, 2011 at 8:1 Comment(4)
This is a bad idea if you have a lot of items in this "LinearListView" because of row reusing.Dickens
@PaNaVTEC: Whats bad about row reusing? It also depends on the adapter if the convertView is being used or not, so what?Baba
your LinearListView is not reusing rows, thats the problem. The listView will show only visible rows and when you scroll will reuse the rows, then you have in memory only visible rows. With your LinearlistView you have in memory all the rows you have populated in the adapter. Also I think is a nice solution for a small set of rowsDickens
Your solution would perfectly fit my current need. But when I implement it, I only get the first item added from my adapter.Dripping
F
3

I dont have enough reputation points to comment but for those only having 1 item appearing in Nappy's solution make sure you set the following in your layout file:

    android:orientation="vertical"

Else it will appear that only one item is being added but in reality they are just being added horizontally...hope this helps someone.

Fixing answered 26/3, 2014 at 15:40 Comment(0)
S
0

You could make one ListView and put all inside it, so the whole page will scroll. You could roll out your own adapter implementation, but I recommend using CommonsWare's excellent MergeAdapter You could add the labels or divider bars with addView() and the lists with addAdapter(). Check out the page for more information on usage, and the demo project.

Subscapular answered 7/7, 2010 at 10:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.