Android CustomListAdapter notifydatachange() 不工作

Posted

技术标签:

【中文标题】Android CustomListAdapter notifydatachange() 不工作【英文标题】:Android CustomListAdapter notifydatachange() is not working 【发布时间】:2014-06-14 01:05:24 【问题描述】:

我想使用自定义 ArrayAdapter 显示项目列表。

我将通过单击按钮插入数据。

MainFragment.java

@Override
        public void onClick(View v) 
            DatabaseClass feed = new DatabaseClass(getActivity());
            new DatabaseClass(getActivity()).getList();
            new MyFragment().updateList();
        

我的布局文件如下。

ma​​in.xml

 <LinearLayout
                android:layout_
                android:layout_
                android:orientation="vertical" >

                <fragment
                    android:id="@+id/update"
                    android:name="com.android.MyFragment"
                    android:layout_
                    android:layout_ />
            </LinearLayout>

MyFragment.java

import java.util.List;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class MyFragment extends ListFragment 

    // creating database reference
    private static DatabaseClass feed;
    private List<CustomModel> customList;
    private static CustomListAdapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        feed = new DatabaseClass(getActivity());
    

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

        // To get List of CustomModel objects
        feed.getList();

        // CUSTOM_LIST is list constant
        adapter = new CustomListAdapter(getActivity(),
                R.layout.update, Utils.CUSTOM_LIST);

        // setting adapter      
        setListAdapter(adapter);
        View view = inflater.inflate(R.layout.update, container, false);

        return view;
    

    @Override
    public void onStart() 
        super.onStart();
    

    // this method is called after inserting data into database
    public void updateList() 
        if (adapter != null) 
            adapter.notifyDataSetChanged();
         else 
            adapter = new CustomListAdapter(getActivity(),
                    R.layout.update, Utils.CUSTOM_LIST);
            adapter.notifyDataSetChanged();
        
    

    private class CustomListAdapter extends ArrayAdapter<CustomModel> 

        private final Context context;
        private final List<CustomModel> list;
        private TextView name, message;

        public CustomListAdapter(Context context, int resource,
                List<CustomModel> list) 
            super(context, resource, list);
            this.context = context;
            this.list = list;
        

        @Override
        public View getView(int position, View convertView, ViewGroup parent) 
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View view = inflater.inflate(R.layout.single_row, parent,
                    false);

            name = (TextView) view.findViewById(R.id.name);
            message = (TextView) view.findViewById(R.id.message);
            CustomModel obj = list.get(position);

            name.setText(obj.getName());
            message.setText(obj.getMessage());

            return view;
        
    

MyFragment.java 的布局文件是

update.xml

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:id="@android:id/list"
 />

我的数据库类是

DatabaseClass.java

    public void getList()
        ourDatabase = this.getReadableDatabase();
        String sql = "SELECT * FROM " + DATABASE_TABLE;
        Cursor c = ourDatabase.rawQuery(sql, null);

        int iName = c.getColumnIndex(KEY_NAME);
        int iMessage = c.getColumnIndex(KEY_MESSAGE);

        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) 
            CustomModel model = new CustomModel();


            model.setName(c.getString(iFromName));
            model.setMessage(c.getString(iMessage));

            Utils.LIST.add(model);
        

点击按钮,数据被插入到数据库中。但它没有反映在 UI 中。 为什么我的列表视图没有更新?

谢谢

【问题讨论】:

为什么我的列表视图没有更新? - 因为出于某种奇怪的原因,每次单击该按钮时,您都会创建一个 new 实例MyFragment,一个根本不用的实例。您需要通过 FragmentManager 从主布局中获取对片段的引用,并在该实例上调用 updateList() 您的适配器基于Utils.CUSTOM_LIST 列表,但在getList() 方法中您更新了Utils.LIST 列表。是哪一个? 这两个常量都只有Utils.LIST。对不起我的错字。我按照你的建议试过了。 FragmentManager manager = getFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); MyFragment fragment = (MyFragment) getFragmentManager().findFragmentById(R.id.update); fragment.updateList(); transaction.commit(); 但是没用。 我能够成功。我使用您的片段管理器将 notifyDataSetChanged() 放入适配器类中。我在调试时遇到了问题,在 UI 更新后发生了数据库插入。 【参考方案1】:

如下更改您的适配器

    private class CustomListAdapter extends ArrayAdapter<CustomModel> 

    private final Context context;
    private final List<CustomModel> list;
    private TextView name, message;

    public CustomListAdapter(Context context, int resource,
            List<CustomModel> list) 
        super(context, resource, list);
        this.context = context;
        this.list = list;
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.single_row, parent, false);

        name = (TextView) view.findViewById(R.id.name);
        message = (TextView) view.findViewById(R.id.message);
        CustomModel obj = list.get(position);

        name.setText(obj.getName());
        message.setText(obj.getMessage());

        return view;
    

    public void updateList(List<CustomModel> list) 

        this.list = list;
        notifyDataSetChanged();

    

所以在你的适配器中添加方法 updateList 并调用方法notifyDataSetChanged();

所以从你的活动而不是调用notifyDataSetChanged(); 调用updateList(List&lt;CustomModel&gt; newList)

我相信这会奏效。

【讨论】:

以上是关于Android CustomListAdapter notifydatachange() 不工作的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在使用 CustomListAdapter 时得到不同大小的列表行,即使我尝试为自定义列表行提供特定值

在android中滚动listView时重新加载图像

如何在 Android Studio 中以除 onCreate 之外的其他方法获取应用程序的上下文?

自定义Listview点击功能

ListView 子对象可点击冲突

Android逆向系列文章— Android基础逆向