【问题标题】:listview adapter not updating after removing an item删除项目后列表视图适配器未更新
【发布时间】:2015-11-27 07:30:26
【问题描述】:

您好,我正在尝试从我的列表视图中删除一个项目,我可以从我的数据库中删除一个项目,但我的适配器没有得到更新,我附上了下面的代码`

public class SavedPolygonFragment extends android.support.v4.app.Fragment implements RefreshListener {
private static String LOG_TAG = SavedPolygonFragment.class.getName();

private String message = "No message";
private ListView          shapeList;
private TextView          textView;
private Button            startMainBtn;
private SavedShapeAdapter savedShapeAdapter;
private long              shapeId;
private float             scaleFactor;
private List<Shape> savedShapes = new ArrayList<>();
private StartDrawingListener startListener;
private DeleteShapesDialog   deleteDialog;

public SavedPolygonFragment() {

}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    startListener = (StartDrawingListener) activity;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_one, container, false);

    savedShapes = getArguments().getParcelableArrayList("shapes");
    AssetLog.verbose(LOG_TAG, "savedshapes.size " + savedShapes.size());
    shapeList = (ListView) view.findViewById(R.id.shapeList);
    textView = (TextView) view.findViewById(R.id.polygonTitle);
    startMainBtn = (Button) view.findViewById(R.id.gotoMain);

    startMainBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startListener.startMainReceived();
        }
    });

    if (!savedShapes.isEmpty() && !savedShapes.equals(null) && savedShapes.size() != 0) {
        textView.setText("Polygons");
        shapeList.setVisibility(View.VISIBLE);
        startMainBtn.setVisibility(View.GONE);


        if (savedShapeAdapter != null) {
            savedShapeAdapter.notifyDataSetChanged();
        } else {

            savedShapeAdapter = new SavedShapeAdapter(savedShapes, getActivity());
            shapeList.setAdapter(savedShapeAdapter);

            shapeList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    MainActivity_.intent(getActivity())
                            .savedProjectId(ProjectShapesActivity.projId)
                            .scaleFactor(ProjectShapesActivity.scaleFactor)
                            .shapeId(((Shape) view.getTag()).getShapeId())
                            .lineId(-1)
                            .pointId(-1)
                            .start();
                }
            });


        }
    }
    else{
        shapeList.setVisibility(View.GONE);
        startMainBtn.setVisibility(View.VISIBLE);

        textView.setText("Sorry no shapes are saved");
    }

    return view;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    registerForContextMenu(shapeList);
}

@Override
public void onRefreshPressed() {
}

@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, view, menuInfo);
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
    shapeId = info.id;
    menu.add(Menu.NONE, R.id.deleteShapes, Menu.NONE, "Delete");
    menu.add(Menu.NONE, R.id.editShapes, Menu.NONE, "Edit");

}

@Override
public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case R.id.refresh:
            return false;

        case R.id.deleteShapes:
            if(deleteDialog == null){
                Bundle bundle = new Bundle();
                bundle.putString("SHAPE", "SHAPE");
                bundle.putLong("shapeId", shapeId);
                deleteDialog = new DeleteShapesDialog();
                deleteDialog.setArguments(bundle);
                deleteDialog.show(getActivity().getFragmentManager().beginTransaction(), "showDeleteDialog");
            }
            return true;
        case  R.id.editShapes:
            return true;

    }
    return super.onContextItemSelected(item);
}


 public void onDataChanged(long shapeid) {

    Shape shape;
    for (int i = 0; i <savedShapes.size() ; i++) {
        shape = savedShapes.get(i);
        if(shape.getShapeId() == shapeid){
            savedShapes.remove(i);
            shapeList.removeViewAt(i);
            shapeList.invalidate();
            savedShapeAdapter.notifyDataSetChanged();
            break;
        }
    }
}

} `

现在,当用户从 deleteDialog 中选择“是”时,我为我的活动编写了一个回调,并且在相应的方法中这就是我所做的

SavedPolygonFragment polygonFragment = new SavedPolygonFragment();
 polygonFragment.onDataChanged(shapeId);

谁能告诉我怎么了

/////编辑1

 public void onDataChanged(long shapeid) {

     savedShapeAdapter.removeItemById(shapeid);

}

还有我的适配器

public void removeItemById(long itemId){
    for(int i =0; i< shapeList.size() ; i++){
        if(shapeList.get(i).getShapeId() == itemId){
            shapeList.remove(i);
        }
    }
    notifyDataSetChanged();
}

【问题讨论】:

    标签: android listview android-listview android-adapter


    【解决方案1】:

    我能够从我的数据库中删除项目,但我的适配器没有得到 更新了

    问题是由以下原因引起的:

    savedShapes.remove(i);
    

    行。

    当前从 SavedPolygonFragment 类中的 ArrayList 中删除项目,而不是从 Adapter 用来填充 ListView 的 ArrayList 中删除项目。

    使用当前方法尝试这种方式将通过每次设置新适配器来工作:

           if(shape.getShapeId() == shapeid){
                savedShapes.remove(i);
                savedShapeAdapter = new SavedShapeAdapter(savedShapes, getActivity());
                shapeList.setAdapter(savedShapeAdapter);
                savedShapeAdapter.notifyDataSetChanged();
                break;
            }
    

    但这并不是每次想要更新ListView时创建和设置Adapter的新对象的优化解决方案。

    正确的做法是在 SavedShapeAdapter 类中创建一个方法,用于删除 Adapter 使用的 ArrayList 的项目,然后在 onDataChanged 方法中调用它:

    public void deleteRowItem(int index){
      this.savedShapes.remove(index);
      this..notifyDataSetChanged();
    }
    

    当想从 ListView 中删除行项目时,现在调用 deleteRowItem

    if(shape.getShapeId() == shapeid){
        savedShapeAdapter.deleteRowItem(i);
        break;
     }
    

    【讨论】:

    • 我像你说的那样尝试过,但在 savedShapeAdapter.removeItemById(shapeid); 处给我 NullPointerException。
    • 我在该行使用了一个断点,它显示为 savedShapeAdapter = null
    • @elsa: 表示在调用 onDataChanged 方法之前不初始化 savedShapeAdapter 对象。所以你的更新代码
    • @elsa:将onDataChanged 方法更改为public void onDataChanged(long shapeid) { if(savedShapeAdapter !=null){savedShapeAdapter.removeItemById(shapeid);}}
    猜你喜欢
    • 2019-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    相关资源
    最近更新 更多