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

2023-12-02

我制作了一个自定义的水平列表视图,效果很好。然后我在 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 代码,请告诉我。谢谢。


Android L Developer Preview 发布后,Google 提供了一个新的 View,名为RecyclerView可以代替ListView and GridView,它使制作水平列表变得更容易,所以我在这里更新我的答案。

此时我们不需要再使用任何库了,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

旧答案:

我用过双向视图就像您一样在垂直列表视图中显示水平列表。这是我的垂直和水平列表视图适配器代码。它对我来说效果很好,所有视图都是可重用的,所有行都单独滚动。我希望这可以帮助你。

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;
    }
}

}

Edit 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" />

推荐应用程序.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;

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在android中的垂直列表中实现horizo​​ntalList 的相关文章

  • 您的应用中的 Google Analytics SDK

    我按照这里的说明进行操作 https developers google com analytics devguides collection android v3 https developers google com analytics
  • Android Studio Canary 3.4 Canary 4:错误:功能插件不支持variant.getApplicationId()

    自从我在新版本上更新了我的项目以来Android Studio 3 4 金丝雀 4 gradle 同步失败 因为 ERROR variant getApplicationId is not supported by feature plug
  • Android Widget ID 是否持久

    在从桌面删除该 Widget 实例之前 您从操作系统收到的用户桌面上特定 Widget 实例的 Widget ID 是否一致 我找不到任何明确说明这一点的文档 但我假设这是因为文档说您可以使用小部件 id 来存储任何实例配置信息 我想将一些
  • 在 Android 市场中以编程方式检查我的应用程序版本

    目前 我正在启动时检查应用程序版本代码 并将其与我的服务器上的最新版本代码进行匹配 并根据此匹配 我发送用户从 Android 市场获取最新更新 它运行良好 但我的问题是我必须手动更改服务器上的最新版本代码 并且我不知道新版本何时发布APK
  • Android 中图像字节表示的每像素字节数

    我目前正在编写一个Android应用程序 需要在其中使用OCR 为了实现这一点 我将 Tesseract 与tesseract android tools 项目 http code google com p tesseract androi
  • Android 在 Windowmanager 中调整视图大小

    这是我的代码 menubuttonClosed li inflate R layout menu button null menubutton ImageButton menubuttonClosed findViewById R id m
  • 使用 RoboSpice 有没有办法从异常中获取 HTTP 错误代码?

    我正在编写一个使用 RoboSpice 的应用程序 在请求侦听器 onRequestFailure SpiceException arg0 中 有没有办法确定该错误是由于发生 401 HTTP 错误而导致的 我有一个后端服务 当令牌过期时
  • Android 游戏偶尔出现延迟

    我正在用 Java 制作一个简单的 Android 游戏 我注意到每 20 40 秒就会出现一些烦人的延迟 首先 我认为它们是由垃圾收集器引起的 但当我检查 LogCat 时 我发现游戏滞后时没有垃圾收集 每当游戏开始滞后时 我都会标记日志
  • 使用 START_STICKY 启动时服务进程被终止后的 onStartCommand

    我一直在阅读 Android 文档 我想知道是否有人可以阐明当以 START STICKY 启动的服务的进程被终止时服务实例会发生什么情况 我假设本地状态数据 实例变量 也丢失了 Android 在重新创建服务时是否会采取任何措施来帮助重新
  • foo.setVisibility(View.GONE) 和parent.removeView(foo) 之间的区别

    如果 foo 是一个视图 那么有什么区别foo setVisibility View GONE and fooParent removeView foo 我对两个语句之前和之后视图的内存消耗特别感兴趣 可见性设置为 GONE 的视图是否会消
  • DialogFragment 关闭事件

    我需要处理 DialogFragment 的结尾 在调用 dismiss 之后 例如 我会在关闭后 包含 片段的活动内显示一个 toast 我该如何处理该事件 覆盖onDismiss 在你的DialogFragment中 或者使用setOn
  • onStart() 到底做了什么? - 安卓[重复]

    这个问题在这里已经有答案了 一段时间以来 我一直想知道 onStart 函数在 android 生命周期中的确切作用 网上的大多数资源只是说 它在您的活动在屏幕上可见之前被调用 但到目前为止我所做的应用程序我从未使用过onStart 我在
  • 活动中列表视图中的粘滞行

    我的列表视图中只有一行应该是粘性的 而不是粘性标题中带有字母的部分或部分 我真的很感激任何关于列表视图在活动中粘性一行而不是片段的帮助 我该怎么做 我真的很感谢任何帮助 提前致谢 使用如下代码 class MyAsyncTask exten
  • 带有工具提示的搜索栏 android

    Hi All 我正在尝试使用工具提示自定义 android 搜索栏 如给定的图像 有没有办法在搜索栏中添加带有拇指的文本视图 或任何其他想法 Thanks 我们可以通过拇指的界限来做到这一点 并在seekbar的progressChange
  • 片段中的 SavedInstanceState 始终为 null

    我使用 XML 以及活动中的 setContentView 将片段附加到活动 A 有一个问题 因为我的片段中有非常动态的视图 所以当方向改变时 我必须恢复所有的观点状态 我有问题 因为我正在使用类似的东西 public void onSav
  • Android SDK WebView调用Activity

    我试图在单击 WebView 组件内的链接时启动活动 我的Webview已加载到里面Main java我想启动SubActivity java当点击网站内的链接时Main java 另外 如何将参数传递给此活动 Example inspec
  • Android:我的应用程序太大并给出“无法执行 dex:方法 ID 不在 [0, 0xffff]: 65536”?

    我正在尝试将我的应用程序与 Box Dropbox 和 Google Drive 集成 所有这 3 项服务都需要许多第 3 方 jar 此外 我的应用程序已经需要一些第三方 jar 现在 当我尝试从 Eclipse 运行我的应用程序时 出现
  • FCM 主题是否适合更多用户?

    我对使用主题消息有点困惑 我的场景是根据通知触发一些作业 请帮助我更多地了解这一点 如果我们正在处理大量用户 则可以使用 FCM 主题向用户发送通知 我们可以只使用数据消息和主题消息吗 使用主题发送的消息是否保证送达 我在 FCM 文档中看
  • 将主题应用到 v7 支持操作栏

    我正在使用support v7库来实现ActionBar在我的应用程序中 我的styles xml file
  • android.view.WindowLeaked - 使用对话框和新意图时

    我已经尝试了 stackoverflow 上提供的所有可能的解决方案 但我仍然在 logcat 中遇到此错误 活动 com xyz MainActivity 泄露了最初在此处添加的窗口 com android internal policy

随机推荐