【问题标题】:Two ListViews in a ScrollViewScrollView 中的两个 ListView
【发布时间】:2016-10-14 20:42:23
【问题描述】:

我知道将两个 ListView 放在一个 ScrollView 中并不是最佳做法。但是,对于我的问题,这是我能想到的最佳解决方案:

我想要两个列表(第一个包含 1-5 个项目,最后一个包含最多 20 个项目)在可滚动视图中彼此下方,每个列表都有自己的标题。 ListViews 本身不应该是可滚动的,它们应该只是改变高度来包装它们的内容。可滚动部分将由 ScrollView 处理。

由于 ListView 本身不支持此功能,因此我使用以下代码:

public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null) {
        // pre-condition
        return;
    }

    int totalHeight = 0;
    int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);

    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
        totalHeight += listItem.getMeasuredHeight();
        Log.d("DEBUG", "TotalHeight:" + totalHeight);
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listAdapter.getCount() * listView.getDividerHeight());
    listView.setLayoutParams(params);
    listView.requestLayout();
}

但是,这会使 ListView 比它们应该的大大约 10 倍。如果我搜索我遇到的问题,我总能找到上述解决方案,但对我来说这似乎不起作用。

有没有办法修复我的代码,或者有更好的方法来解决这个问题?

XML:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.miscoriadev.svvirgoapp.fragments.frag_activiteiten"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingTop="@dimen/activity_vertical_margin">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/tv_acti_komende_activiteiten"
            android:textSize="32sp"
            android:text="Komende activiteiten"
            android:textColor="@color/TextColorDark"
            android:gravity="center"/>

        <ListView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/tv_acti_komende_activiteiten"
            android:id="@+id/lv_komende_activiteiten">
        </ListView>

        <TextView
            android:paddingTop="@dimen/activity_vertical_margin"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="32sp"
            android:text="Afgelopen activiteiten"
            android:textColor="@color/TextColorDark"
            android:gravity="center"
            android:layout_marginLeft="@dimen/activity_horizontal_margin"
            android:id="@+id/tv_acti_afgelopen_activiteiten"
            android:layout_below="@id/lv_komende_activiteiten"/>

        <ListView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/tv_acti_afgelopen_activiteiten"
            android:id="@+id/lv_afgelopen_activiteiten">
        </ListView>

    </RelativeLayout>

【问题讨论】:

  • 您需要两个列表同时滚动并显示在同一个屏幕上?如果是这样,我建议将GridView 与 2 列一起使用。如果没有,我建议使用ViewPagerTabLayout。这是一个如何做的教程:guides.codepath.com/android/…
  • 不,我只是希望它们位于彼此下方,并且在一个可滚动的框架中有两个列表
  • 我相信如果你使用水平的ListViews而不是垂直的会更方便。我什至建议使用水平或垂直的RecyclerView

标签: java android xml listview scrollview


【解决方案1】:

我解决了我的问题,方法是从 LinearLayout 创建我自己的列表 UI 元素,方法是将视图膨胀到其中,就像 ListAdapter 对 ListView 所做的那样。

尽管有点粗略,您可以轻松地重写此代码以接受 ListAdapter 对象作为项目源。通过重写 setListItems() 方法以通过 ListAdapter 对象的 getView() 方法获取它的视图。

package com.miscoriadev.svvirgoapp.util;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.miscoriadev.svvirgoapp.MainActivity;
import com.miscoriadev.svvirgoapp.R;

import java.util.ArrayList;

/**
 * Created by milanvandijck on 14/10/2016.
 */

public class UnscrollableListView extends LinearLayout{

private Context context;
private LayoutInflater inflater;
private MainActivity mainActivity;

public UnscrollableListView(Context context) {
    super(context);
    this.context = context;
    this.mainActivity = (MainActivity)context;
    this.setOrientation(LinearLayout.VERTICAL);

    if(!this.isInEditMode()) {
        inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
    }
}

public UnscrollableListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    this.mainActivity = (MainActivity)context;
    this.setOrientation(LinearLayout.VERTICAL);

    if(!this.isInEditMode()) {
        inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
    }
}


public void setListItems(ArrayList<ActivityItem> list){

    for (int i = 0; i <= list.size()-1; i++){
        UnscrollableListView.viewHolder holder = new UnscrollableListView.viewHolder();
        View rowView;
        final ActivityItem item = list.get(i);

        Log.d(getClass().getName(), "Adding view: " + item.getTitle());

        // Check if there are activities
        if (item.getTitle().equals("0_0") && item.getLocation().equals("0_0")){
            rowView = inflater.inflate(R.layout.activiteiten_listitem_emptylist, null);
            this.addView(rowView);
        }

        rowView = inflater.inflate(R.layout.activiteiten_listitem, null, false);

        holder.tv_name=(TextView) rowView.findViewById(R.id.eventName);
        holder.tv_date=(TextView) rowView.findViewById(R.id.eventDate);
        holder.tv_time=(TextView) rowView.findViewById(R.id.eventTime);
        holder.tv_Location= (TextView) rowView.findViewById(R.id.eventLocation);
        holder.img_poster=(ImageView) rowView.findViewById(R.id.eventPoster);

        holder.tv_name.setText(item.getTitle());
        holder.img_poster.setImageBitmap(item.getImage());
        holder.tv_date.setText(item.getDateString());
        holder.tv_time.setText(item.getTimeString());
        holder.tv_Location.setText(item.getLocation());

        rowView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                mainActivity.openActivityDetails(item);
            }
        });

        this.addView(rowView, i);
    }

    this.invalidate();

}

public class viewHolder
{
    TextView tv_name;
    TextView tv_date;
    TextView tv_time;
    TextView tv_Location;
    ImageView img_poster;
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-16
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    相关资源
    最近更新 更多