简体   繁体   English

在对话框的按钮上单击从ListView删除行

[英]Delete row from ListView on Dialogue Box's button click

I am trying to delete a row in listview as well as from database when user dialogue box is shown to use user while pressing for long time. 当试图长时间按住用户对话框显示使用用户时,我试图从数据库中删除列表视图以及从数据库中删除一行。

在此处输入图片说明

I have tried following code: 我尝试了以下代码:

Place.java (For model - getter and setter methods) Place.java (对于模型-getter和setter方法)

public class Place {
    int _id;
    private String mname;
    private double mlatitude,mlongitude;
    private String mplacedetails;

    public Place(int id, String name, double latitude, double longitude,String placedetails)
        {
            this._id = id;
          mname = name;
          mlatitude = latitude;
          mlongitude = longitude;
          mplacedetails = placedetails;


    }

    public Place(String name, double latitude, double longitude,String placedetails)
    {

        mname = name;
        mlatitude = latitude;
        mlongitude = longitude;
        mplacedetails = placedetails;

    }

    public Place() {

    }
    public int getID(){
        return this._id;
    }


    public void setID(int id){
        this._id = id;
    }

    public void setname(String placename)
    {
        mname = placename;


    }

    public String getname()
    {
        return mname;


    }

    public void setlatitude(double latitude)
    {
        mlatitude=latitude;


    }

    public double getlatitude()
    {
        return mlatitude;


    }


    public void setlongitude(double longitude)
    {
        mlongitude = longitude;


    }

    public double getlongitude()
    {
        return mlongitude;


    }


    public void  setPlacedetails(String placedetails)
    {

        mplacedetails = placedetails;
    }


    public String getplacedetails()
    {
        return mplacedetails;
    }


}

PlaceAdapter.java - for adapter of ListView listview_places PlaceAdapter.java-用于ListView listview_places适配器

public class PlacesAdapter extends ArrayAdapter<Place>{

    Context mcontext;
    int mlayoutResourceId;
  List<Place> mdata = null;
    View row;


    public PlacesAdapter(Context context, int layoutResourceId, List<Place> data) {
        super(context, layoutResourceId, data);
        mlayoutResourceId = layoutResourceId;
        mcontext = context;
        mdata = data;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        row = convertView;
        PlaceHolder holder = null;

        if(row == null)
        {
            LayoutInflater inflater = ( (Activity) mcontext).getLayoutInflater();
            row = inflater.inflate(mlayoutResourceId, parent, false);

            holder = new PlaceHolder(row);


            row.setTag(holder);
            Log.d("my","new row is inflated for listview current position");

        }
        else
        {
            holder = (PlaceHolder)row.getTag();
            Log.d("my","row is taken from the holder");
        }

        Place p = mdata.get(position);
        holder.txt_place_title.setText(p.getname());
        holder.txt_place_details.setText(p.getplacedetails());

        return row;
    }

    class PlaceHolder
    {
        TextView txt_place_title;
        TextView txt_place_details;


        public PlaceHolder(View v){

            txt_place_title = (TextView)row.findViewById(R.id.txt_Place_Title);
            txt_place_details = (TextView)row.findViewById(R.id.txt_Place_Details);

        }
    }
}

MySQLiteHelper.java - for databse controller MySQLiteHelper.java-用于数据库控制器

public class MySqliteHelper extends SQLiteOpenHelper{

    private static final int DATABASE_VERSION = 1;

    private static final String DATABASE_NAME = "MyApplicationDatabase";

    private static final String KEY_ID = "id";
    private static final String KEY_PLACENAME = "placename";
    private static final String KEY_PLACEDETAILS = "placedetails";
    private static final String KEY_LATITUDE = "latitude";
    private static final String KEY_LONGITUDE = "longitude";

    private static final String TABLE_NAME = "places";


    public MySqliteHelper(Context context) {
        super(context, DATABASE_NAME,null, DATABASE_VERSION);


    }

    @Override
    public void onCreate(SQLiteDatabase db) {



        //actual query = create table places (id primary key autoincrement, placename taxt, latitude real, longitude real);
        String query =  "CREATE TABLE " +TABLE_NAME + "( " + KEY_ID+
                " INTEGER PRIMARY KEY, " + KEY_PLACENAME+
                " TEXT, "+ KEY_PLACEDETAILS+
                " TEXT, "+ KEY_LATITUDE+
                " REAL, "+KEY_LONGITUDE+ " REAL)";


                db.execSQL(query);
                Log.d("my", "Successfully created table: " + query);



    }



    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS places");

        this.onCreate(db);
    }


    public void addPlaces(Place place)
    {

        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues convalues = new ContentValues();



        convalues.put(KEY_PLACENAME,place.getname());
        convalues.put(KEY_LATITUDE,place.getlatitude());
        convalues.put(KEY_LONGITUDE,place.getlongitude());
        convalues.put(KEY_PLACEDETAILS,place.getplacedetails());

          db.insert(TABLE_NAME, null, convalues);
          Log.d("my","db.insert(TABLE_NAME, null, convalues)");
          Log.d("my", "Values inserted");
          db.close();

    }

    public Place getPlace(int id) {
        Place place = null;
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.query(TABLE_NAME, new String[]{KEY_ID, KEY_LATITUDE, KEY_LONGITUDE,
                        KEY_PLACENAME, KEY_PLACEDETAILS}, KEY_ID + "=?",
                new String[]{String.valueOf(id)}, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
        }
        place = new Place(cursor.getInt(cursor.getColumnIndex("_ID")), cursor.getString(cursor.getColumnIndex(KEY_PLACENAME)),
                    cursor.getDouble(cursor.getColumnIndex(KEY_LATITUDE)), cursor.getDouble(cursor.getColumnIndex(KEY_LONGITUDE)), cursor.getString(cursor.getColumnIndex(KEY_PLACEDETAILS)));

        cursor.close();
        db.close();

        return place;
    }

    public List<Place> getAllPlaces() {
   List<Place> placeList = new ArrayList<Place>();



        SQLiteDatabase db = this.getWritableDatabase();

        String selectQuery = "SELECT  * FROM " + TABLE_NAME;

        Cursor cursor = db.rawQuery(selectQuery, null);
        Log.d("my","query fired");
        Log.d("my",cursor.toString());

        if (cursor.moveToFirst()) {

            Log.d("my","in movetofirst()");

            do {

                Log.d("my","in do");
                Place place = new Place();

                place.setname(cursor.getString(cursor.getColumnIndex(KEY_PLACENAME)));
                place.setlatitude(cursor.getDouble(cursor.getColumnIndex(KEY_LATITUDE)));
                place.setlongitude(cursor.getDouble(cursor.getColumnIndex(KEY_LONGITUDE)));
                place.setPlacedetails(cursor.getString(cursor.getColumnIndex(KEY_PLACEDETAILS)));

                placeList.add(place);
            } while (cursor.moveToNext());
        }


        return placeList;
    }

    public void deletePlaces(Place place)
    {

        SQLiteDatabase db = this.getWritableDatabase();



        db.delete(TABLE_NAME, KEY_ID + " = ?",
                new String[] { String.valueOf(place.getID()) });
        db.close();
    }

    public int updatePlaces(Place place) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_PLACENAME, place.getname());
        values.put(KEY_PLACEDETAILS, place.getplacedetails());


        return db.update(TABLE_NAME, values, KEY_ID + " = ?",
                new String[] { String.valueOf(place.getID()) });
    }

    public void deleteByName(String name) {
        SQLiteDatabase db= this.getWritableDatabase();
        db.delete(TABLE_NAME, KEY_PLACENAME +"=?", new String [] { name });
        db.close();
    }

}

and ShowPlaces.java Activity has fragment named PlaceholderFragment.java : - where adapter is set to listview_places and dialogue box is shown on itemlongclick. ShowPlaces.java活动具有名为PlaceholderFragment.java的片段:-其中适配器设置为listview_places并且在itemlongclick上显示对话框。

public class PlaceholderFragment extends Fragment {
        public ListView listview_places;

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_show_place, container, false);



            MySqliteHelper db = new MySqliteHelper(getActivity().getBaseContext());

           List<Place> places = db.getAllPlaces();




            for (Place p : places){
                String log = "name:" +p.getname() + " ,details: " + p.getplacedetails();

                Log.d("my", log);
            }

            listview_places = (ListView)rootView.findViewById(R.id.listView_places);

            final PlacesAdapter places_adapter = new PlacesAdapter(getActivity(),R.layout.listview_item_row,places);

            Log.d("my", "adapter constructor is working");

            listview_places.setAdapter(places_adapter);



            listview_places.setLongClickable(true);

            listview_places.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

                public boolean onItemLongClick(AdapterView<?> parent, View view,
                                               final int pos, long id) {

                    new AlertDialog.Builder(getActivity())
                            .setTitle("Delete Place")
                            .setMessage("Are you sure you want to delete this place?")
                            .setPositiveButton("Delete", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {

                                }
                            })
                            .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {
                                    // do nothing
                                }
                            })
                            .setIcon(android.R.drawable.ic_menu_delete)
                            .show();

                    return true;
                }
            });

db.close();
        return rootView;
        }

    }

What I want to do is to to delete the row in listview_places as well as from database when user clicks on delete button in DialougeBox. 当用户单击DialougeBox中的删除按钮时,我想删除listview_places的行以及从数据库中删除该行。

For database as you can see there is already a method named deleteByName() in MySQLiteHelper.java . 如您所见,对于数据库, MySQLiteHelper.java已经有一个名为deleteByName()MySQLiteHelper.java

So, thinks looks much more complex too me...I can say what I want to do is that I want to invoke deleteByName method of MySQLiteHelpder and remove method of ListView list_view_places in between 所以,我觉得也要复杂得多...我可以说我想做的是我要调用MySQLiteHelpder deleteByName方法并在两者之间remove ListView list_view_places方法。

    .setPositiveButton("Delete", new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int which) {

//I want to delete place from listview and database here.
                                        }
                                    })

I have tried many times something like: 我已经尝试过很多次了:

 nameArray.remove(position);

        // dh.Deleteitem();
            adapter.notifyDataSetChanged();
            adapter=new ListAdapter(getActivity(), nameArray);
         list.setAdapter(adapter);

But..sometimes it didn't work showing that adapter should be final if it is accessed from inner class . 但是..有时无法显示adapter should be final if it is accessed from inner class and if I make adapter final than showing notifyDatasetChanged can not be resolved . 并且如果我使适配器final notifyDatasetChanged can not be resolved显示出notifyDatasetChanged can not be resolved

What should I do? 我该怎么办?

Now I solved it! 现在我解决了!

After working for hours, I found solution for this: 工作了几个小时后,我找到了解决方案:

Inside my listview onItemClickListener and then inside dialogue box's positive button onclick, I used, 在我的列表视图中,使用onItemClickListener ,然后在对话框的肯定按钮onclick中,

                            Place place = places_adapter.getItem(pos);
                            places_adapter.remove(place);
                            db.deletePlaces(place);
                            places_adapter.notifyDataSetChanged();

You need to only remove from adapter . 您只需要从adapter删除。 Adapter works as controller. 适配器用作控制器。 At last don't forget notifyDataSetChanged() . 最后不要忘了notifyDataSetChanged()

whole code: 整个代码:

  listview_places.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
       new AlertDialog.Builder(getActivity())
                                .setTitle("Delete Place")
                                .setMessage("Are you sure you want to delete this place?")
                                .setPositiveButton("Delete", new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int which) {

                                        Place place = places_adapter.getItem(pos);
                                        places_adapter.remove(place);
                                        db.deletePlaces(place);
                                        places_adapter.notifyDataSetChanged();

                                    }
                                })
});

First off, don't create your MySqliteHelper in a life cycle method of a View Component like a Fragment, unless you're really sure you won't need it anywhere else and kniw what you're doing. 首先,不要在像Fragment这样的View Component的生命周期方法中创建MySqliteHelper ,除非您确实确定在其他任何地方都不需要它,并且知道自己在做什么。 Better create it inside the Application class and access it with App.inst().yourDbMngr().delete(Place.class, placeToDelete) . 最好在Application类中创建它,并使用App.inst().yourDbMngr().delete(Place.class, placeToDelete) Then you won't need to think about member vars when deleting pojos. 这样,在删除pojos时就无需考虑成员变量。 Also make your adapter a member var of the fragment hoatung it, as you'd likely access it quite often. 还要使您的适配器成为片段的成员变量,因为您可能会经常访问它。 onCreate() is the right place to do so. onCreate()是执行此操作的正确位置。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM