片段中的自定义列表不起作用

Custom List in Fragment wont work

所以我是 Android 编程的新手 我正在尝试制作自定义 ListView。我遵循 YouTube (https://www.youtube.com/watch?v=gAIB4fTm2BA) 上的教程,但我无法在片段上使用它。

public class DriverFragment extends Fragment implements GeneralFragment   {

ListView listView;
public DriverFragment() {

    // Required empty public constructor
}



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view;
    view = inflater.inflate(R.layout.fragment_driver, container, false);
    listView = (ListView) view.findViewById(R.id.driverList);
    DriverAdapter driverAdapter = new DriverAdapter(getActivity().getApplicationContext(),R.layout.driver_listview);
    listView.setAdapter(driverAdapter);
    Driver a = new Driver("John Smith","Johnsmith@example.com","123");

    driverAdapter.add(a);

    return view;
}

驱动适配器:

public class DriverAdapter extends ArrayAdapter {
ArrayList list = new ArrayList();

public DriverAdapter(Context context, int resource) {
    super(context, resource);
}


static  class Holder{
    TextView NAME;
    TextView EMAIL;
    TextView PHONE;
}
public void add(Driver driver) {
    list.add(driver);
    super.add(driver);

}

@Override
public Object getItem(int position) {
    return this.list.get(position);
}

public  int getCount(){
    return  this.list.size();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row;
    row = convertView;
    Holder holder;
    if(convertView == null) {
        LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = layoutInflater.inflate(R.layout.driver_listview, parent, false);
        holder = new Holder();
        holder.NAME = (TextView) row.findViewById(R.id.driverName);
        holder.EMAIL = (TextView) row.findViewById(R.id.driverMail);
        holder.PHONE = (TextView) row.findViewById(R.id.driverPhone);
        row.setTag(holder);
    }else {
        holder  = (Holder) row.getTag();

    }
    Driver driver = (Driver)getItem(position);
    holder.NAME.setText(driver.getName());
    holder.EMAIL.setText(driver.getMail());
    holder.PHONE.setText(driver.getPhone());

    return  row;

}

XML

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

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:text="DriverName"
    android:id="@+id/driverName"
    android:padding="10dp" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:text="DriverMail"
    android:id="@+id/driverMail"
    android:layout_gravity="center_horizontal"
    android:padding="10dp" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:text="DriverPhone"
    android:id="@+id/driverPhone"
    android:padding="10dp" />

看起来您在向 ListView 添加任何内容之前将适配器设置为 ListView,这很好,但是您必须调用 adapter.notifyDataSetChanged() 才能使用新数据更新列表。

尽管如此,我还是建议您更改创建适配器的方式。每次我使用任何类型的适配器时,我都会先创建我的数据列表,然后通过构造函数将其传递进来。然后将其设置为我的列表视图。所以喜欢:

    View view;
    view = inflater.inflate(R.layout.fragment_driver, container, false);
    listView = (ListView) view.findViewById(R.id.driverList);

    Driver a = new Driver("John Smith","Johnsmith@example.com","123");
    ArrayList<Driver> drivers = new ArrayList();
    drivers.add(a);

    DriverAdapter driverAdapter = new DriverAdapter(getActivity().getApplicationContext(),R.layout.driver_listview, drivers);
    listView.setAdapter(driverAdapter);

这只是我将要执行的操作的一个粗略示例,我建议您阅读 Google 中的一些示例。如果可能,还请阅读 RecyclerViews 而不是 ListViews。

https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html

https://www.bignerdranch.com/blog/recyclerview-part-1-fundamentals-for-listview-experts/

首先,如果你真的应该看看一些很好的教程,比如

在 Android 中使用列表 (ListView) - 教程 http://www.vogella.com/tutorials/AndroidListView/article.html

假设您的 Fragment 一切正常并且可见,让我们关注您的 Adapter。因为你的 DriverAdapter 有它自己的 ArrayList 数据,所以在它的 add() 方法中调用 super.add() 是没有意义的。您只需调用 notifyDataSetChanged() 让适配器知道它应该刷新 UI 上的内容。试试这样的东西..

public class DriverAdapter extends BaseAdapter {
ArrayList<Driver> data = new ArrayList();

public void add(Driver driver) {
    data.add(driver);
    notifyDataSetChanged();
}

public void addAll(List<Driver> drivers) {
    data.addAll(drivers);
    notifyDataSetChanged();
}

@Override
public Driver getItem(int position) {
    return data.get(position);
}

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

public int getCount() {
    return data.size();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Holder holder;

    if (convertView == null) {
        LayoutInflater layoutInflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = layoutInflater.inflate(R.layout.item_driver_row, parent, false);
        holder = new Holder();
        holder.name = (TextView) convertView.findViewById(R.id.driverName);
        holder.email = (TextView) convertView.findViewById(R.id.driverMail);
        holder.phone = (TextView) convertView.findViewById(R.id.driverPhone);
    } else {
        holder = (Holder) convertView.getTag();

    }

    Driver driver = getItem(position);
    holder.name.setText(driver.getName());
    holder.email.setText(driver.getEmail());
    holder.phone.setText(driver.getPhone());
    convertView.setTag(holder);

    return convertView;
}

static class Holder {
    TextView name;
    TextView email;
    TextView phone;
}

}

我最后的回答似乎没有帮助,我很快就整理了一些东西。

我强烈建议阅读更多有关此主题的内容,因为列表和适配器是 Android 开发不可或缺的一部分,了解其工作原理非常有帮助。

public class Driver {

    private String name;
    private String email;
    private String phone;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}

片段:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment, container, false);
        ListView listView = (ListView) view.findViewById(R.id.listView);

        Driver a = new Driver();
        a.setName("Name");
        a.setEmail("Email");
        a.setPhone("Phone");

        ArrayList<Driver> drivers = new ArrayList<>();
        drivers.add(a);

        DriverAdapter driverAdapter = new DriverAdapter(getActivity().getApplicationContext(),R.layout.driver_listview, drivers);
        listView.setAdapter(driverAdapter);

        return view;

    }

适配器

public class DriverAdapter extends ArrayAdapter<Driver> {


    public DriverAdapter(Context context, int resource, List<Driver> objects) {
        super(context, resource, objects);
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row;
        row = convertView;
        Holder holder;
        if(convertView == null) {
            LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = layoutInflater.inflate(R.layout.driver_listview, parent, false);
            holder = new Holder();
            holder.name = (TextView) row.findViewById(R.id.driverName);
            holder.email = (TextView) row.findViewById(R.id.driverMail);
            holder.phone = (TextView) row.findViewById(R.id.driverPhone);
            row.setTag(holder);
        }else {
            holder  = (Holder) row.getTag();

        }
        Driver driver = getItem(position);
        holder.name.setText(driver.getName());
        holder.email.setText(driver.getEmail());
        holder.phone.setText(driver.getPhone());

        return  row;
    }

    public class Holder {
        protected TextView name;
        protected TextView email;
        protected TextView phone;
    }
}

适配器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="horizontal">

    <TextView
        android:id="@+id/driverName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="DriverName"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="@android:color/black" />

    <TextView
        android:id="@+id/driverMail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:padding="10dp"
        android:text="DriverMail"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="@android:color/black" />

    <TextView
        android:id="@+id/driverPhone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="DriverPhone"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="@android:color/black" />

</LinearLayout>

如果这对您没有帮助,则说明您的片段在设备上显示有问题。因为我自己测试过,它在屏幕上显示正确。