在android中的垂直列表中实现horizo​​ntalList

时间:2014-02-27 06:12:42

标签: android android-listview horizontallist

我制作了一个自定义的水平列表视图。然后我在ListView控件中实现了相同的水平列表。但是当我运行相同的时候,我得到的只是一个空白输出。该列表似乎没有表现出来。

在调试时我发现,添加到列表视图的适配器包含项目(水平列表)。

所以,问题显然不在于没有正确填充的项目,而是视图的呈现不正确。

以下是垂直列表视图的代码:

XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.twowaylistview.HorizontalListView
        android:id="@+id/lstHor"
        android:layout_height="100dp"
        android:layout_width="fill_parent">
    </com.example.twowaylistview.HorizontalListView>
</LinearLayout>

这里是水平列表中单个项目的XML

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="100dp">

    <ImageView
        android:id="@+id/imgListItem"
        android:layout_height="85dp"
        android:layout_width="85dp"
      ..            />

   ...

</RelativeLayout>

如果您需要java代码,请告诉我。感谢。

2 个答案:

答案 0 :(得分:13)

在发布Android L开发者预览版之后,Google提供了一个名为RecyclerView的新视图,它可以取代ListViewGridView,这样可以更轻松地制作水平列表,因此我更新了回答这里。

此时我们不再需要使用任何库,RecyclerView就足够了。以下是RecyclerView制作水平列表的代码(我不是要解释RecyclerView的详细用法):

MainActivity.java

public class MainActivity extends AppCompatActivity {

    List<List<String>> mDataList;

    private RecyclerView mVerticalList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        prepareData();
        initListView();
    }

    private void prepareData() {
        mDataList = new ArrayList<>();
        int vItemCount = 25;
        int hItemCount = 20;
        for (int i = 0; i < vItemCount; i++) {
            List<String> hList = new ArrayList<>();
            for (int j = 0; j < hItemCount; j++) {
                hList.add("Item." + j);
            }
            mDataList.add(hList);
        }
    }

    private void initListView() {
        mVerticalList = (RecyclerView) findViewById(R.id.vertical_list);
        mVerticalList.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        VerticalAdapter verticalAdapter = new VerticalAdapter();
        verticalAdapter.setData(mDataList);
        mVerticalList.setAdapter(verticalAdapter);
    }

    private static class VerticalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        private List<List<String>> mDataList;

        public VerticalAdapter() {
        }

        public void setData(List<List<String>> data) {
            mDataList = data;
            notifyDataSetChanged();
        }

        private class HorizontalListViewHolder extends RecyclerView.ViewHolder {

            private TextView title;
            private RecyclerView horizontalList;
            private HorizontalAdapter horizontalAdapter;

            public HorizontalListViewHolder(View itemView) {
                super(itemView);
                Context context = itemView.getContext();
                title = (TextView) itemView.findViewById(R.id.item_title);
                horizontalList = (RecyclerView) itemView.findViewById(R.id.item_horizontal_list);
                horizontalList.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
                horizontalAdapter = new HorizontalAdapter();
                horizontalList.setAdapter(horizontalAdapter);
            }
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            Context context = parent.getContext();
            View itemView = LayoutInflater.from(context).inflate(R.layout.vertical_list_item, parent, false);
            HorizontalListViewHolder holder = new HorizontalListViewHolder(itemView);
            return holder;
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder rawHolder, int position) {
            HorizontalListViewHolder holder = (HorizontalListViewHolder) rawHolder;
            holder.title.setText("Horizontal List No." + position);
            holder.horizontalAdapter.setData(mDataList.get(position));
            holder.horizontalAdapter.setRowIndex(position);
        }

        @Override
        public int getItemCount() {
            return mDataList.size();
        }
    }

    private static class HorizontalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        private List<String> mDataList;
        private int mRowIndex = -1;
        private int[] mColors = new int[]{Color.RED, Color.BLUE, Color.GREEN, Color.MAGENTA, Color.DKGRAY};

        public HorizontalAdapter() {
        }

        public void setData(List<String> data) {
            if (mDataList != data) {
                mDataList = data;
                notifyDataSetChanged();
            }
        }

        public void setRowIndex(int index) {
            mRowIndex = index;
        }

        private class ItemViewHolder extends RecyclerView.ViewHolder {

            private TextView text;

            public ItemViewHolder(View itemView) {
                super(itemView);
                text = (TextView) itemView.findViewById(R.id.item_text);
                itemView.setOnClickListener(mItemClickListener);
            }
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            Context context = parent.getContext();
            View itemView = LayoutInflater.from(context).inflate(R.layout.horizontal_list_item, parent, false);
            ItemViewHolder holder = new ItemViewHolder(itemView);
            return holder;
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder rawHolder, int position) {
            ItemViewHolder holder = (ItemViewHolder) rawHolder;
            holder.text.setText(mDataList.get(position));
            holder.itemView.setBackgroundColor(mColors[position % mColors.length]);
            holder.itemView.setTag(position);
        }

        @Override
        public int getItemCount() {
            return mDataList.size();
        }

        private View.OnClickListener mItemClickListener = new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                int columnIndex = (int) v.getTag();
                int rowIndex = mRowIndex;

                String text = String.format("rowIndex:%d ,columnIndex:%d", rowIndex, columnIndex);
                showToast(v.getContext(), text);
                Log.d("test", text);
            }
        };
    }

    private static Toast sToast;

    public static void showToast(Context context, String text) {
        if (sToast != null) {
            sToast.cancel();
        }
        sToast = Toast.makeText(context, text, Toast.LENGTH_LONG);
        sToast.show();
    }
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/vertical_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

horizontal_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/item_text"
        android:textColor="@android:color/white"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center_vertical"/>

</LinearLayout>

vertical_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/item_title"
        android:background="@android:color/darker_gray"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:gravity="center_vertical"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/item_horizontal_list"
        android:layout_width="match_parent"
        android:layout_height="50dp"/>
</LinearLayout>

在2015-05-20更新

旧答案:

我使用TwoWayView在垂直列表视图中显示水平列表,就像您一样。这是我的纵向和横向列表视图适配器代码。它适用于我,所有视图都可重用,所有行都单独滚动。我希望这对你有帮助。

public class RecommendAppAdapter extends BaseAdapter implements
    OnItemClickListener {
public static final String TAG = "RecommendAppAdapter";

//Vertical list data
private Map<String, List<RecommendApp>> mMapData = new TreeMap<String, List<RecommendApp>>();

private OnItemClickListener mOnItemClickListener = null;

//Vertical list adapter
public RecommendAppAdapter(Context context) {
}

@Override
public boolean isEmpty() {
    return mMapData == null || mMapData.isEmpty();
}

@Override
public int getCount() {
    if (!isEmpty()) {
        return mMapData.size();
    } else {
        return 0;
    }
}

//Get horizental list data
@Override
public List<RecommendApp> getItem(int position) {
    if (!isEmpty() && isAvaliablePostion(position)) {
        Iterator<Entry<String, List<RecommendApp>>> entries = mMapData
                .entrySet().iterator();
        int i = 0;
        Entry<String, List<RecommendApp>> entry = null;
        while (entries.hasNext()) {
            entry = entries.next();
            if (i == position) {
                return entry.getValue();
            }
            i++;
        }
    }
    return null;
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    ItemAdapter innerListAdapter = null;
    if (convertView == null) {
        holder = new ViewHolder();
        convertView = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.item_recommend_app, null);
        //Some views in vertical list
        holder.type = (TextView) convertView
                .findViewById(R.id.item_rec_app_type_name);
        //Get horizental list view
        holder.hListView = (TwoWayView) convertView
                .findViewById(R.id.item_rec_app_list);
        //Bind adapter on horizental list
        innerListAdapter = new ItemAdapter();
        holder.hListView.setAdapter(innerListAdapter);
        //Bind item click listener on horizental list
        holder.hListView.setOnItemClickListener(this);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
        innerListAdapter = (ItemAdapter) holder.hListView.getAdapter();
    }
    //Get horizental list data
    List<RecommendApp> itemList = getItem(position);

    holder.type.setText(itemList.get(0).getTypeName());

    //Deliver horizental list adapter data
    innerListAdapter.setData(itemList);

    return convertView;
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
        long id) {
    switch (parent.getId()) {
    case R.id.item_rec_app_list:
        if (mOnItemClickListener != null) {
            mOnItemClickListener.onItemClick(parent, view, position, id);
        }
        break;
    }
}

public void setOnItemClickListener(OnItemClickListener listener) {
    mOnItemClickListener = listener;
}

public void setData(Map<String, List<RecommendApp>> data) {
    mMapData.clear();
    if (data != null && !data.isEmpty()) {
        mMapData.putAll(data);
    }
    notifyDataSetChanged();
}

private boolean isAvaliablePostion(int position) {
    if (position >= 0 && position < getCount()) {
        return true;
    } else {
        return false;
    }
}


private class ViewHolder {
    public TextView type;
    public TwoWayView hListView;
}

//Horizontal list adapter
//All work are just like the normal use of ListView 
private class ItemAdapter extends BaseAdapter {

    //Horizontal list data
    private List<RecommendApp> mInnerData = null;

    private FinalBitmap mFinalBitmap = FinalBitmap.create(MyApp
            .getInstance());

    @Override
    public boolean isEmpty() {
        return mInnerData == null || mInnerData.isEmpty();
    }

    @Override
    public int getCount() {
        if (!isEmpty()) {
            return mInnerData.size();
        }
        return 0;
    }


    @Override
    public RecommendApp getItem(int position) {
        if (position >= 0 && position < getCount()) {
            return mInnerData.get(position);
        }
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolderInner holder = null;
        if (convertView == null) {
            holder = new ViewHolderInner();
            Context context = parent.getContext();
            convertView = LayoutInflater.from(context).inflate(
                    R.layout.item_recommend_app_inner, null);
            holder.name = (TextView) convertView
                    .findViewById(R.id.item_rec_app_inner_name);
            holder.icon = (ImageView) convertView
                    .findViewById(R.id.item_rec_app_inner_icon);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolderInner) convertView.getTag();
        }
        RecommendApp item = ItemAdapter.this.getItem(position);
        holder.name.setText(item.getAppName());
        mFinalBitmap.display(holder.icon, item.getIcon());
        return convertView;
    }

    public void setData(List<RecommendApp> data) {
        mInnerData = data;
        notifyDataSetChanged();
    }

    private class ViewHolderInner {
        public TextView name;
        public ImageView icon;
    }
}

}

编辑1

RecommendApp是一个POJO,其中包含在水平列表中显示的项目的数据。

item_recommend_app.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/item_rec_app_type_name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/item_rec_app_type_name_bg"
    android:gravity="left|center_vertical"
    android:paddingBottom="@dimen/item_rec_app_type_name_paddingBottom"
    android:paddingLeft="@dimen/item_rec_app_type_name_paddingLeft"
    android:paddingTop="@dimen/item_rec_app_type_name_paddingTop"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textIsSelectable="false" />

<com.phonetools.appmanager.widget.TwoWayView
    android:id="@+id/item_rec_app_list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" />

item_recommend_app_inner.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/item_rec_app_inner_padding" >

<ImageView
    android:id="@+id/item_rec_app_inner_icon"
    android:layout_width="@dimen/item_rec_app_inner_icon_width"
    android:layout_height="@dimen/item_rec_app_inner_icon_height"
    android:layout_gravity="center"
    android:contentDescription="@string/image_desc"
    android:scaleType="fitCenter" />

<TextView
    android:id="@+id/item_rec_app_inner_name"
    android:layout_width="@dimen/item_rec_app_inner_icon_width"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:ellipsize="end"
    android:gravity="center"
    android:singleLine="true"
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:textIsSelectable="false" />

RecommendApp.java:

public class RecommendApp {
public RecommendApp() {
}


private String packageName;


private String appName;


private String versionName;


private float size;


private String icon;


private int typeId;


private String typeName;


private String installLink;


private String description;


private float ratingScore;


private long installedSum;

}

答案 1 :(得分:0)

而不是列表视图来显示水平和垂直滚动列表。您可以使用表格布局。 下面是我的代码,其中两个侧滚动都表现良好。

您也可以根据需要进行自定义。

创建MainActivity.java

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TableRow.LayoutParams;
import android.widget.TextView;

public class MainActivity extends Activity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

        TableRow.LayoutParams wrapWrapTableRowParams = new     TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    int[] fixedColumnWidths = new int[]{20, 20, 20, 20, 20, 20};
    int[] scrollableColumnWidths = new int[]{20, 20, 20, 30, 30, 30};
    int fixedRowHeight = 50;
    int fixedHeaderHeight = 60;

    TableRow row = new TableRow(this);
    //header (fixed vertically)
    TableLayout header = (TableLayout) findViewById(R.id.table_header);
    row.setLayoutParams(wrapWrapTableRowParams);
    row.setGravity(Gravity.CENTER);

    row.addView(makeTableRowWithText("col 1", fixedColumnWidths[0], fixedHeaderHeight));
    row.addView(makeTableRowWithText("col 2", fixedColumnWidths[1], fixedHeaderHeight));
    row.addView(makeTableRowWithText("col 3", fixedColumnWidths[2], fixedHeaderHeight));
    row.addView(makeTableRowWithText("col 4", fixedColumnWidths[3], fixedHeaderHeight));
    row.addView(makeTableRowWithText("col 5", fixedColumnWidths[4], fixedHeaderHeight));
    row.addView(makeTableRowWithText("col 6", fixedColumnWidths[5], fixedHeaderHeight));
    header.addView(row);

    //header (fixed horizontally)

    TableLayout fixedColumn = (TableLayout) findViewById(R.id.fixed_column);

    //rest of the table (within a scroll view)

    TableLayout scrollablePart = (TableLayout) findViewById(R.id.scrollable_part);

    for(int i = 0; i < 50; i++)
    {
       TextView fixedView = makeTableRowWithText("row number " + i,   scrollableColumnWidths[0], fixedRowHeight);

        fixedColumn.addView(fixedView);
        row = new TableRow(this);
        row.setLayoutParams(wrapWrapTableRowParams);
        row.setGravity(Gravity.CENTER); 
        row.setBackgroundColor(Color.WHITE);
        row.addView(makeTableRowWithText("value 2", scrollableColumnWidths[1], fixedRowHeight));
        row.addView(makeTableRowWithText("value 3", scrollableColumnWidths[2], fixedRowHeight));
        row.addView(makeTableRowWithText("value 4", scrollableColumnWidths[3], fixedRowHeight));
        row.addView(makeTableRowWithText("value 5", scrollableColumnWidths[4], fixedRowHeight));
        row.addView(makeTableRowWithText("value 6", scrollableColumnWidths[5], fixedRowHeight));
        scrollablePart.addView(row);
   }
}

//util method
private TextView recyclableTextView;
 public TextView makeTableRowWithText(String text, int widthInPercentOfScreenWidth, int   fixedHeightInPixels) {
int screenWidth = getResources().getDisplayMetrics().widthPixels;
recyclableTextView = new TextView(this);
recyclableTextView.setText(text);
recyclableTextView.setTextColor(Color.BLACK);
recyclableTextView.setTextSize(20);
recyclableTextView.setWidth(widthInPercentOfScreenWidth * screenWidth / 100);
recyclableTextView.setHeight(fixedHeightInPixels);
return recyclableTextView;
  }
}

创建activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:id="@+id/fillable_area">
<TableLayout
    android:id="@+id/table_header"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"/>
<ScrollView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <LinearLayout android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center_horizontal"
        android:id="@+id/fillable_area">
        <TableLayout
            android:id="@+id/fixed_column"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <HorizontalScrollView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <TableLayout
                android:id="@+id/scrollable_part"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"/>
        </HorizontalScrollView>
    </LinearLayout>
</ScrollView>
</LinearLayout>

试试这个我会解决你的需求。

由于