显示列表视图中的项目集

时间:2015-04-20 08:11:54

标签: android listview

我有一个列表视图(显示在购物车内选择的项目),它应显示在运行时添加的项目。当我将列表视图的高度设置为wrap_content时,它将仅显示第一个项目。此列表视图位于滚动视图内,其中包含一些其他小部件,如按钮。检索值时不会出现ant错误,因为当我将高度更改为500dp时,它会正确显示所有项目。如何在不使用wrap_content的情况下指定列表视图的高度,因为它不符合我的要求?谢谢。

3 个答案:

答案 0 :(得分:0)

你错过的是刷新视图。

对内容进行任何更改后,您需要View.requestLayout()。这会强制视图重绘并显示您添加的所有项目。

如果您使用自定义适配器(将其添加到getView(..)方法中),您可以在ListView适配器中执行此操作。

或者,您可以在将项目添加到适配器后执行此操作。

编辑:对于您的情况,也许您不希望滚动视图占据整个屏幕。所以为您设置滚动视图的布局边界并将列表视图设置为wrap_content。这应该为您提供可滚动的布局您指定的区域。如果您需要更具体的帮助,请提供相关代码。

答案 1 :(得分:0)

我不确定尝试这个:更改@android:layout_below=""属性。

 <ScrollView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/scrollView2"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" >


<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:weightSum="1">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageView"
        android:src="@drawable/ic_launcher"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center_horizontal" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Items Selected"
        android:id="@+id/textView2"
        android:layout_gravity="center_horizontal"
        android:layout_below="@+id/imageView"
        android:layout_alignLeft="@+id/imageView"
        android:layout_alignStart="@+id/imageView"
        android:textColor="#ffff6b30"
        android:textStyle="bold" />

    <ListView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/carList"
        android:layout_below="@+id/textView2"
        android:layout_gravity="bottom"
        android:fastScrollEnabled="false"
        android:smoothScrollbar="false"
        android:scrollingCache="false" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Calculate Bill"
        android:id="@+id/button2"
        android:layout_gravity="right"
        android:textColor="#fffff536"
        android:background="#ffff6714"
        android:layout_marginTop="30dp"
        android:layout_below="@+id/carList"
        android:layout_centerHorizontal="true"
        android:focusableInTouchMode="false" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Delete Item"
        android:id="@+id/button11"
        android:textColor="#fffff536"
        android:background="#ffff6714"
        android:layout_below="@+id/button2"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Refresh Cart"
        android:id="@+id/button12"
        android:textColor="#fffff536"
        android:background="#ffff6714"
        android:layout_below="@+id/button11"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:onClick="refreshButtonClick" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Back to Main Menu"
        android:id="@+id/button13"
        android:textColor="#fffff536"
        android:background="#ffff6714"
        android:layout_below="@+id/button12"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:onClick="bakToMainButtonClick" />

</LinearLayout>

答案 2 :(得分:0)

不推荐使用,但可以将ListView放在ScrollView中。 如果在ScrollView中嵌套ListView,它将破坏触摸。他们表现得很奇怪,只是行不通。如果你想在ScrollView中有一个可滚动的ListView,例如。要在ListView下面显示一些内容或支持小屏幕(想想黑莓......),这可能是一个解决方案。 ScrollView中的ListView,都是可滚动的。 此外,下面的解决方案是hacky。如果它破坏你的设置,不要怪我 免责声明:此解决方案由各种SO帖子组合在一起+由我调整。我不再有消息来源了。

将ScrollView作为xml中的head元素,并在其中放入Relative Layout并将ListView嵌套在其中。使ScrollView为match_parent和ListView wrap_content。 触摸将被破坏,因此您必须使用这个特殊的ScrollView(新文件中的新类):

public class ScrollViewExt extends ScrollView {
    private ScrollViewListener scrollViewListener = null;
    public ScrollViewExt(Context context) {
        super(context);
    }

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

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

    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }
}

您看到我使用ScrollViewListener,使用此名称创建一个接口,让您的Activity或Fragment实现它(也是新文件,这次是一个接口):

public interface ScrollViewListener 
{
    void onScrollChanged(ScrollViewExt scrollView, 
        int x, int y, int oldx, int oldy);
}

接下来,您必须在使用布局的Activity或Fragment中自己滚动。要实现滚动,您必须知道您的内容(ListView +其他内容)有多大,例如。通过使用背景图片:

    //get the size of the image
    int bitmapWidth = yourBitmapWidth;
    int bitmapHeight = yourBitmapHeight;

    // set maximum scroll amount (based on center of image)
    int maxX = (int)((bitmapWidth / 2) - (displayWidth / 2));
    int maxY = (int)((bitmapHeight / 2) - (displayHeight / 2));


    // set scroll limits
    final int maxLeft = (maxX * -1);
    final int maxRight = maxX;
    final int maxTop = (maxY * -1);
    final int maxBottom = maxY;

这就是RelativeLayout的用法:你可以通过设置TouchListener将它用作假的ScrollView。

    yourRelativeLayout.setOnTouchListener(new View.OnTouchListener()
    {
        float downX, downY;
        int totalX, totalY;
        int scrollByX, scrollByY;
        @Override
        public boolean onTouch(View view, MotionEvent event)
        {

            if(hasToScroll)
            {

            float currentX, currentY;
            switch (event.getAction())
            {
                case MotionEvent.ACTION_DOWN:
                    downX = event.getX();
                    downY = event.getY();
                    break;

                case MotionEvent.ACTION_MOVE:
                    currentX = event.getX();
                    currentY = event.getY();
                    scrollByX = (int)(downX - currentX);
                    scrollByY = (int)(downY - currentY);

                    if (currentY > downY)
                    {
                        if (totalY == maxTop)
                        {
                            scrollByY = 0;
                        }
                        if (totalY > maxTop)
                        {
                            totalY = totalY + scrollByY;
                        }
                        if (totalY < maxTop)
                        {
                            scrollByY = maxTop - (totalY - scrollByY);
                            totalY = maxTop;
                        }
                    }

                    if (currentY < downY)
                    {
                        if (totalY == maxBottom)
                        {
                            scrollByY = 0;
                        }
                        if (totalY < maxBottom)
                        {
                            totalY = totalY + scrollByY;
                        }
                        if (totalY > maxBottom)
                        {
                            scrollByY = maxBottom - (totalY - scrollByY);
                            totalY = maxBottom;
                        }
                    }

                    yourRelativeLayout.scrollBy(0, scrollByY);
                    downX = currentX;
                    downY = currentY;
                    break;

            }

            return true;

            }
            else
            {
                return false;
            }
        }

    });

尚未完成。我们需要检测何时允许滚动哪个视图。

@Override
public void onScrollChanged(ScrollViewExt scrollView, int x, int y, int oldx, int oldy) {
    // We take the last son in the scrollview
    View view = (View) scrollView.getChildAt(scrollView.getChildCount() - 1);
    int diff = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));

    // if diff is zero, then the bottom has been reached
    if (diff == 0) {
        isBottom = true;
        isTop = false;

    }
    else if(scrollView.getScrollY() < 10)
    {
        isBottom = false;
        isTop = true;

    }
    else
    {
        isBottom = false;
        isTop = false;

    }
}

public void scrollViewIsAllowedToScroll(Boolean isAllowed)
{
    scrollView.requestDisallowInterceptTouchEvent(!isAllowed);
}

应该将Listview设置为全局,因为您还需要手动实现其滚动:

public void addOnTouchListenerToListView()
{       

    try{
    if((listView.getChildAt(listView.getChildCount() - 1).getBottom()) > listView.getHeight())
    {
        listView.setOnTouchListener(new ListView.OnTouchListener() {
            @SuppressLint("NewApi")
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                Boolean alldown = false;
                Boolean allup = false;

                if (listView.getLastVisiblePosition() == listView.getAdapter().getCount() -1 && listView.getChildAt(listView.getChildCount() - 1).getBottom() <= listView.getHeight())
                {
                    //The list is scrolled all the way down here
                    alldown = true;
                    alldown = false;
                }
                else if (listView.getFirstVisiblePosition() == 0 && listView.getChildAt(0).getTop() >= 0)
                {
                    //The list is scrolled all the way up here
                    allup = true;
                    alldown = false;
                }
                else
                {
                    // The list is scrolled anywhere between top and bottom
                    allup = false;
                    alldown = false;
                }

                // filter different touch events
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                    {
                        // save the position where list was touched first
                        downXValue = event.getX();
                        downYValue = event.getY();

                        v.onTouchEvent(event);
                        return true;
                    }

                    case MotionEvent.ACTION_UP:
                    {                       
                        v.onTouchEvent(event);
                        return false;
                    }

                    case MotionEvent.ACTION_MOVE:
                    {

                        // get the current position of the touch
                        float currentY = event.getY();

                        // if the current touch position is smaller than the first touch, the touch (finger) has moved down, so the list has to scroll up
                        if (downYValue < currentY) {
                            direction = Constants.kDirectionDown;
                        }
                        // if the current touch position is bigger than the first touch, the touch (finger) has moved up, so the list has to scroll down
                        else if (downYValue > currentY)
                        {
                            direction = Constants.kDirectionUp;
                        }

                        // cases to figure out when the scrollView is allowed to scroll instead of the list
                        if(isTop && allup)
                        {
                            scrollViewIsAllowedToScroll(true);
                        }
                        else if(isBottom && allup)
                        {
                            if(direction == Constants.kDirectionDown)
                            {
                                scrollViewIsAllowedToScroll(true);
                            }
                            else if(direction == Constants.kDirectionUp)
                            {
                                scrollViewIsAllowedToScroll(false);
                            }
                        }
                        else if(isBottom && alldown)
                        {
                            scrollViewIsAllowedToScroll(false);
                        }
                        else if (!allup && !alldown)
                        {
                            scrollViewIsAllowedToScroll(false);
                        }
                        else if (isBottom)
                        {
                            scrollViewIsAllowedToScroll(false);
                        }


                        v.onTouchEvent(event);
                        return true;
                    }

                    case MotionEvent.ACTION_CANCEL:
                    {   
                        v.onTouchEvent(event);
                        return false;
                    }

                    default:
                    {
                        v.onTouchEvent(event);
                        return false;
                    }
                }
            }
        });
    }
    else
    {
        scrollViewIsAllowedToScroll(true);
    }
    }catch(Exception e)
    {
        e.printStackTrace();
    }
}

所以,就是这样。我不知道你想要的是什么,但它确实给了我很多帮助。

编辑:almoust忘了这件事: 您需要调用addOnTouchListenerToListView一次,但只能等待一段时间,因为您的listView不会立即填充。此外,您可能只想调用一次,因为之后仍然设置了ListView。

@Override
public void onResume(){
    super.onResume();
    adjustScrolling();
}

public void adjustScrolling()
{

        handler = new Handler();
        runnable = null;
        runnable = new Runnable() {
               @Override
               public void run() {
                   if(listView.getHeight() > 0)
                    {
                        firstStart = false;
                        handler.removeCallbacks(runnable);
                        addOnTouchListenerToListView();
                    }
                   else
                   {
                       handler.postDelayed(this, 500);
                   }
               }
            };
        handler.postDelayed(runnable, 0);

}