在android中的垂直列表中实现horizontalList [英] Implementing horizontalList inside a vertical list in android
问题描述
我制作了一个工作正常的自定义水平列表视图.然后我在 ListView 控件中实现了相同的水平列表.但是当我运行相同的时候,我得到的只是一个空白的输出.该列表似乎没有填充.
I have made a custom Horizontal List view which works fine. I then implemented the same horizontal list inside a ListView control. But when I run the same, all I get is a blank output. The list does not seem to poupulate.
在调试时我发现添加到列表视图的适配器包含项目(水平列表).
On debugging I found, that the adapter which was added to the list view contain the items(Horizontal lists).
所以,问题显然不是没有正确填充的项目,而是没有正确呈现的视图.
So, the problem is clearly not of items not populating properly, its of the view not rendered properly.
这是垂直列表视图的代码:
Here is the code for vertical list view:
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
and here is XML for individual item in the horizontal list
<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代码,请告诉我.谢谢.
let me know if you need the java code. Thanks.
推荐答案
Android L Developer Preview 发布后,Google 提供了一个名为 RecyclerView
的新视图,它可以替代 ListView
和GridView
,它可以更容易地制作水平列表,所以我在这里更新我的答案.
After Android L Developer Preview published, Google supply a new View called RecyclerView
which can replace ListView
and GridView
, it makes it easier to make a horizontal list, so I update my answer here.
此时我们不需要再使用任何库,RecyclerView
就足够了.这是我通过 RecyclerView
制作水平列表的代码(我不是要解释 RecyclerView
的详细用法):
We don't need to use any library anymore at this time, RecyclerView
is just enough. Here is the code which I make a horizontal list by RecyclerView
(I am not trying to explain detailed usage of 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 更新
update at 2015-05-20
我已经使用 TwoWayView 像您一样在垂直列表视图中显示水平列表.这是我的垂直和水平列表视图适配器代码.它对我来说很好用,所有视图都是可重用的,所有行都单独滚动.我希望这可以帮助你.
I have used TwoWayView to show horizontal lists in a vertical listview just like you. Here is my vertical and horizontal listview adapter code .It works fine for me, all views are reusable, all the rows scroll individually. I hope this may help you.
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;
}
}
}
RecommendApp 是一个 POJO,其中包含显示在水平列表中的项目的数据.
RecommendApp is a POJO which contain data of an item that shows in the horizontal list.
item_recommend_app.xml :
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:
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:
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;
}
这篇关于在android中的垂直列表中实现horizontalList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!