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