【问题标题】:How to set CardViews from ArrayList in ListView如何在 ListView 中从 ArrayList 设置 CardViews
【发布时间】:2019-10-12 01:17:32
【问题描述】:

所以我正在使用从 firebase 获取数据的 Android 应用程序,基本上是我保存到特定类的 ArrayList 中的汽车列表。我想显示CardView 的列表,每个都有一个汽车对象,换句话说,每张卡片都显示有关该汽车的信息(型号、公里、价格等)。我知道我应该这样做的方式是在我的布局中使用 ListView,但我无法让适配器工作。

这个想法是它显示类似这样的东西,但带有汽车照片和其他东西: enter image description here

自从我最近开始研究这种结构以来,我对这种结构并不是很熟悉,但我想我了解它的工作原理。我制作了卡片视图布局模型来显示每辆车,并尝试制作ViewHolder 类。谢谢指教!我的代码:

Vehicle类:

    public class Vehicle {

    int anio, cv, kms, puertas;
    double precio;
    String combustible, foto, marca, modelo, palanca;

    public Vehicle() {

    } //setters and getters are too, but I omitted them

我的cardview_template.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="wrap_content"
    android:padding="16dp"
    >

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cv"
        >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp"
            >

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/car_photo"
                android:src="@drawable/ic_home_icon"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:layout_marginRight="16dp"
                />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/marca"
                android:text="Mercedes-Benz"
                android:layout_toRightOf="@+id/car_photo"
                android:layout_alignParentTop="true"
                android:textSize="30sp"
                />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/kms"
                android:text="128000"
                android:layout_toRightOf="@+id/car_photo"
                android:layout_below="@+id/marca"
                />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/precio"
                android:text="2018"
                android:layout_toRightOf="@+id/car_photo"
                android:layout_below="@+id/kms"
                />

        </RelativeLayout>

    </android.support.v7.widget.CardView>

</LinearLayout>

mi MainActivity 中方法 onCreate() 中的部分代码: 我编辑了代码。请参阅下面的编辑

最后,我用于adapter 的类。我认为问题出在这里: 我编辑了课程。请参阅下面的编辑


编辑 因此,按照建议,我用 RecyclerView 更改了 ListView,但它也不起作用。我没有收到任何错误:CardViews 根本没有出现在我的 RecyclerView 中。

这是我的新适配器类和 MainActivity onCreate() 中的新代码

适配器:

public class VehicleListAdapter extends RecyclerView.Adapter<VehicleListAdapter.VehicleViewHolder> {

private ArrayList<Vehicle> mVehicleList;

public static class VehicleViewHolder extends  RecyclerView.ViewHolder {

    public ImageView mImageView;
    public TextView mTextView1;
    public TextView mTextView2;
    public TextView mTextView3;


    public VehicleViewHolder(View itemView) {
        super(itemView);
        mImageView = itemView.findViewById(R.id.car_photo);
        mTextView1 = itemView.findViewById(R.id.marca);
        mTextView2 = itemView.findViewById(R.id.modelo);
        mTextView3 = itemView.findViewById(R.id.precio);
    }
}

public VehicleListAdapter(ArrayList<Vehicle> vehicleslist) {
    mVehicleList = vehicleslist;
}

@NonNull
@Override
public VehicleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    //Links the cardview layout and prepares the ViewHolder
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_template, parent, false);
    VehicleViewHolder vvh = new VehicleViewHolder(v);
    return vvh;
}

@Override
public void onBindViewHolder(@NonNull VehicleViewHolder holder, int position) {
    /*
    *   Links the layout elements with the variables in this class
    *   and put the object values in them
    */
    Vehicle currentVehicle = mVehicleList.get(position);

    //Uses Picasso librarie to set the image in the holder's ImageView
    Picasso.get().load(currentVehicle.foto).into(holder.mImageView);

    holder.mTextView1.setText(currentVehicle.getMarca());
    holder.mTextView2.setText(currentVehicle.getModelo());
    holder.mTextView3.setText(String.valueOf(currentVehicle.getPrecio()));
}

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

主活动:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);


    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
(...)
    //Prepares the recycler view and shows the data
    mRecyclerView = findViewById(R.id.recyclerView);
    mRecyclerView.setHasFixedSize(true);
    mLayoutManager = new LinearLayoutManager(this);
    mAdapter = new VehicleListAdapter(vehiclesList);

    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setAdapter(mAdapter);
}

EDIT2

好吧,我遇到了一个非常奇怪的事情。如果我在onCreate() 中的任何位置放置一个调试点,然后执行应用程序调试,它就可以正常工作。我完全迷路了。

如果我不这样做,它会显示如下:

在模拟器和我的实际手机中都可以使用

【问题讨论】:

    标签: java android listview arraylist cardview


    【解决方案1】:

    首先你应该使用 recyclerView 而不是 ListView。

    这是你错过的:

    在 onCreate 方法中替换这个:

    VehicleListAdapter adapter = new VehicleListAdapter(this, R.layout.content_main, vehiclesList);
    

    VehicleListAdapter adapter = new VehicleListAdapter(this, R.layout.cardview_template, vehiclesList);
    

    【讨论】:

      【解决方案2】:

      我知道我应该这样做的方式是在我的布局中使用 ListView,但我无法让适配器工作。

      实际上,您需要知道 Android 应用程序有一定数量的 RAM 可供使用,如果您考虑处理图像,这将更少。因此,不建议将 ListView 用于图像处理,特别是对于大量图像。解决此问题的方法是使用 RecyclerView,而不是 ListView

      另外如果你需要使用RecyclerView,你需要为Adapter Class扩展RecyclerViewAdapter,它会有自己的ViewHolder,子类。

      RecyclerView 易于使用,但最初很难。练习后你就会掌握它的窍门。

      你可以关注这个youtube链接RecyclerView + CardView - Part 1 - LAYOUTS AND CUSTOM OBJECTS - Android Studio Tutorial

      如果您仍有疑问,请发表评论,我很乐意回答。

      【讨论】:

      • 感谢您的回答和 yt 教程。但是,我仍然有同样的问题: CardViews 没有出现在我的 RecyclerView 中。我完全按照教程所说的做了,但没有任何效果......我会更新帖子,以便您可以看到我的新课程。
      • 所以你得到的错误实际上很容易调试,如果它是我认为的那样。请同时参考 ViewHolder 类中的 CardView。给它添加一个功能,比如 cv.setVisibility(true);在 onBindViewHolder() 方法中
      • 即使这不起作用,尝试用 if(mRecyclerView!=null) 包围 setAdapter 函数,这样您就知道数据存在
      • 一切似乎都很好。如果我关闭并打开应用程序(不会终止手机中的进程),卡片会列出。数据存在,当我调试时,它会正确加载。我认为问题在于方法 onBindViewHolder 在应用程序首次执行时没有执行。
      • 使用Handler先加载数据。首先使用较少数量的质量较差的图像(例如 3-5 个图像)进行测试。设置适配器,只有在数据完全获取后。为此,使用 DatabaseSnapshot 的getChildrenCount() 方法,获取计数,并在获取的列表等于子项的数量后显示列表。在此获取发生之前,使用不确定的进度条来显示加载动画。一个像样的图像大约是 200kB 到 300kB,以 200dp tp 250dp 的高度查看。
      猜你喜欢
      • 1970-01-01
      • 2011-11-09
      • 2016-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-28
      相关资源
      最近更新 更多