繁体   English   中英

AlertDialog关闭后在片段中更新ListView

[英]Update ListView in Fragment after AlertDialog dismiss

我有一个包含ListViewFragment 我正在使用对话框将一些值添加到数据库,并且我想在关闭对话框后更新此ListView 另外,当我更改选项卡时,不会更新ListView但是在打开和关闭应用程序时,也会更新ListView

FragmentDialog类如下:

分段:

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

    listViewTeams = rootView.findViewById(R.id.listView_teams);

    TeamDatabase teamDatabase = new TeamDatabase(getContext());
    teamDatabase.open();
    arrayListTeam = teamDatabase.getAllTeams();
    teamDatabase.close();

    int resID = R.layout.team_list_item;
    teamListArrayAdapter = new TeamListArrayAdapter(getContext(), resID, arrayListTeam);
    listViewTeams.setAdapter(teamListArrayAdapter);

    return rootView;
}

对话框onClick方法:

@Override
public void onClick(View view) {
   int id = view.getId();

   switch (id){
       case R.id.button_alertDialogAddTeam_cancel:
           this.dismiss();
           break;
       case R.id.button_alertDialogAddTeam_ok:
           Team team = new Team();
           team.setName(editTextTeamName.getText().toString());
           team.setCode(editTextTeamCode.getText().toString());

           TeamDatabase teamDatabase = new TeamDatabase(getContext());
           teamDatabase.open();
           if(teamDatabase.addNewTeam(team)) {
               Toast.makeText(getContext(), team.getCode() + " - " +
                       team.getName() + " was added successfully", Toast.LENGTH_SHORT).show();
           }

           this.dismiss();
           break;
   }
}

TeamDatabase类:

    public static final String TABLE_NAME = "team";

private static final String KEY_ID = "id";
private static final String KEY_NAME = "name";
private static final String KEY_CODE = "code";
private static final String KEY_EMBLEM = "emblem";

private Context context;

public static final String CREATE_TABLE = "CREATE TABLE "+
        TABLE_NAME + " ("+
        KEY_ID  + " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, "+
        KEY_NAME + " TEXT NOT NULL, "+
        KEY_CODE + " TEXT NOT NULL, " +
        KEY_EMBLEM + " TEXT);";


public TeamDatabase(Context context) {
    super(context);
    this.context = context;
}

public boolean addNewTeam(Team team){
    ContentValues contentValues = new ContentValues();

    contentValues.put(KEY_NAME, team.getName());
    contentValues.put(KEY_CODE, team.getCode());

    return db.insert(TABLE_NAME, null, contentValues) > 0;
}

public ArrayList<Team> getAllTeams()
{
    ArrayList<Team> teams = new ArrayList<Team>();

    Cursor cursor = db.query(TABLE_NAME, new String[]{KEY_ID,
            KEY_NAME,
            KEY_CODE}, null, null, null, null, null);

    while(cursor.moveToNext()) {

        Team team = new Team();

        team.setId(cursor.getInt(cursor.getColumnIndex(KEY_ID)));
        team.setName(cursor.getString(cursor.getColumnIndex(KEY_NAME)));
        team.setCode(cursor.getString(cursor.getColumnIndex(KEY_CODE)));

        teams.add(team);
    }
    return teams;
}

DatabaseHelper类:

private static final String DATABASE_NAME = "fixtureCreator.db";
private static final int DATABASE_VERSION = 1;

public SQLiteDatabase db;

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

}

@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
    sqLiteDatabase.execSQL(TeamDatabase.CREATE_TABLE);
}



@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersinon) {
    Log.w("TaskDBAdapter", "Upgrading from version " +
            oldVersion + " to " + newVersinon + ", which will destroy all old data");

    sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TeamDatabase.TABLE_NAME);
    onCreate(sqLiteDatabase);
}

public DatabaseHelper open() throws SQLException {
    try{
        db = this.getWritableDatabase();
    }catch (SQLException e){
        db = this.getReadableDatabase();
    }
    return this;
}

public void close(){
    db.close();
}

在第一个活动中单击该项目时,请使用startActivityForResult()启动第二个活动

然后在“第二个活动”中,关闭对话框后,在该按钮调用的onClick中,

intent.putExtra("new data", "item text");
setResult(RESULT_OK, intent);
finish();

现在您回到第一个Activity,在这里您必须实现onActivityResult()回调。

您可以从该意图的附加对象中提取数据,并在数组中设置相应项,然后调用notifyDataSetChanged()。

理想情况下,这就是您应该如何做。

您应该在关闭对话框之前调用notifyDataSetChanged

teamListArrayAdapter.notifyDataSetChanged();

您应该在下面更改类似这样的代码

   @Override
public void onClick(View view) {
   int id = view.getId();

   switch (id){
       case R.id.button_alertDialogAddTeam_cancel:
           this.dismiss();
           break;
       case R.id.button_alertDialogAddTeam_ok:
           Team team = new Team();
           team.setName(editTextTeamName.getText().toString());
           team.setCode(editTextTeamCode.getText().toString());

           TeamDatabase teamDatabase = new TeamDatabase(getContext());
           teamDatabase.open();
           if(teamDatabase.addNewTeam(team)) {
               Toast.makeText(getContext(), team.getCode() + " - " +
                       team.getName() + " was added successfully", Toast.LENGTH_SHORT).show();
           }
           arrayListTeam = teamDatabase.getAllTeams();
           teamListArrayAdapter.notifyDataSetChanged();
           this.dismiss();
           break;
   }
}

可以通过在每次单击Dialog然后在适配器上调用notifyDataSetChanged()后保存数据后获取数据来解决此问题。 但是,有一种更优雅的方式来实现这种行为,这将使用内容观察器解决您的两个问题。

如果数据库表中有内容观察者,则需要先声明一个引用表的URI。

public static final Uri DB_TABLE_TEAM_URI = Uri
            .parse("sqlite://" + Constants.ApplicationPackage + "/" + DB_TABLE_TEAM);

// DB_TABLE_TEAM refers to the database table that you have for storing teams.

现在,在您的addNewTeam函数中,您需要执行以下操作。

public boolean addNewTeam(Team team) {
    // .. Save the team in database
    // Notify the observer about the change in the content
    context.getContentResolver().notifyChange(DBConstants.DB_TABLE_TEAM_URI, null);
}

每当在团队表中添加或更新条目时,都需要调用notifyChange()函数。

现在,在“ Activity或“ Fragment您需要在cursor上注册观察者,并从团队表中获取团队数据。

cursor = teamDatabase.getAllTeamsInCursor();
this.registerContentObserver(cursor, DBConstants.DB_TABLE_TEAM_URI);

现在填充您ListView使用cursor将它传递给你的适配器ListView 在团队表中插入新数据后,该列表将自动更新。

更新资料

修改TeamDatabase类中的addNewTeam函数,如下所示。

public static final Uri DB_TABLE_TEAM_URI = Uri
        .parse("sqlite://" + Constants.ApplicationPackage + "/" + DB_TABLE_TEAM);

public boolean addNewTeam(Team team){
    ContentValues contentValues = new ContentValues();

    contentValues.put(KEY_NAME, team.getName());
    contentValues.put(KEY_CODE, team.getCode());

    boolean success = db.insert(TABLE_NAME, null, contentValues) > 0;
    context.getContentResolver().notifyChange(DBConstants.DB_TABLE_TEAM_URI, null);
    return success;
}

要使用LoaderCallbacks实现功能,首先需要在Fragment implement LoaderCallbacks的接口。 因此,您的Fragment的声明将看起来像。

public class TeamsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
    // .... Code
}

现在,您需要重写LoaderCallbacks接口随附的功能。

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {

    return new SQLiteCursorLoader(getActivity()) {
        @Override
        public Cursor loadInBackground() {
            // Initialize your database
            TeamDatabase teamDatabase = new TeamDatabase(getActivity());

            Cursor cursor = teamDatabase.getAllTeams();

            if (cursor != null) {
                // Register the content observer here
                this.registerContentObserver(cursor, DBConstants.DB_TABLE_TEAM_URI);
            }

            return cursor;
        }
    };
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    // Set the cursor in your adapter. Handle null values in your setCursor function in your adapter. The cursor might return null when the table is empty.
    teamAdapter.setCursor(cursor);
    teamAdapter.notifyDataSetChanged();
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
}

现在,在Fragment onCreateView函数中,您需要启动加载程序以从表中获取数据。

getLoaderManager().initLoader(0, null, this).forceLoad();

销毁加载程序,并在onDestroyView函数中取消注册接收程序。

@Override
public void onDestroyView() {
    getLoaderManager().destroyLoader(0);
    super.onDestroyView();
}

我缺少要在此处添加的SQLiteCursorLoader类。

package com.wooz.observer.databases;

import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;

public abstract class SQLiteCursorLoader extends AsyncTaskLoader<Cursor> {
    private final ForceLoadContentObserver mObserver;

    private Uri mUri;
    private String[] mProjection;
    private String mSelection;
    private String[] mSelectionArgs;
    private String mSortOrder;

    private Cursor mCursor;

    /* Runs on a worker thread */
    @Override
    public abstract Cursor loadInBackground();

    /**
     * Registers an observer to get notifications from the content provider
     * when the cursor needs to be refreshed.
     */
    public void registerContentObserver(Cursor cursor, Uri observerUri) {
        cursor.registerContentObserver(mObserver);
        cursor.setNotificationUri(getContext().getContentResolver(), observerUri);
    }

    /* Runs on the UI thread */
    @Override
    public void deliverResult(Cursor cursor) {
        try {
            if (isReset()) {
                // An async query came in while the loader is stopped
                if (cursor != null) {
                    cursor.close();
                }
                return;
            }
            Cursor oldCursor = mCursor;
            mCursor = cursor;

            if (isStarted()) {
                super.deliverResult(cursor);
            }

            if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
                oldCursor.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Creates an empty unspecified CursorLoader.  You must follow this with
     * calls to {@link #setUri(Uri)}, {@link #setSelection(String)}, etc
     * to specify the query to perform.
     */
    public SQLiteCursorLoader(Context context) {
        super(context);
        mObserver = new ForceLoadContentObserver();
    }

    /**
     * Creates a fully-specified CursorLoader.  See
     * {@link ContentResolver#query(Uri, String[], String, String[], String)
     * ContentResolver.query()} for documentation on the meaning of the
     * parameters.  These will be passed as-is to that call.
     */
    public SQLiteCursorLoader(Context context, Uri uri, String[] projection, String selection,
                              String[] selectionArgs, String sortOrder) {
        super(context);
        mObserver = new ForceLoadContentObserver();
        mUri = uri;
        mProjection = projection;
        mSelection = selection;
        mSelectionArgs = selectionArgs;
        mSortOrder = sortOrder;
    }

    /**
     * Starts an asynchronous load of the contacts list data. When the result is ready the callbacks
     * will be called on the UI thread. If a previous load has been completed and is still valid
     * the result may be passed to the callbacks immediately.
     * <p>
     * Must be called from the UI thread
     */
    @Override
    protected void onStartLoading() {
        if (mCursor != null) {
            deliverResult(mCursor);
        }
        if (takeContentChanged() || mCursor == null) {
            forceLoad();
        }
    }

    /**
     * Must be called from the UI thread
     */
    @Override
    protected void onStopLoading() {
        // Attempt to cancel the current load task if possible.
        cancelLoad();
    }

    @Override
    public void onCanceled(Cursor cursor) {
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
    }

    @Override
    protected void onReset() {
        super.onReset();

        // Ensure the loader is stopped
        onStopLoading();

        if (mCursor != null && !mCursor.isClosed()) {
            mCursor.close();
        }
        mCursor = null;
    }

    public Uri getUri() {
        return mUri;
    }

    public void setUri(Uri uri) {
        mUri = uri;
    }

    public String[] getProjection() {
        return mProjection;
    }

    public void setProjection(String[] projection) {
        mProjection = projection;
    }

    public String getSelection() {
        return mSelection;
    }

    public void setSelection(String selection) {
        mSelection = selection;
    }

    public String[] getSelectionArgs() {
        return mSelectionArgs;
    }

    public void setSelectionArgs(String[] selectionArgs) {
        mSelectionArgs = selectionArgs;
    }

    public String getSortOrder() {
        return mSortOrder;
    }

    public void setSortOrder(String sortOrder) {
        mSortOrder = sortOrder;
    }

    @Override
    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
        super.dump(prefix, fd, writer, args);
        writer.print(prefix);
        writer.print("mUri=");
        writer.println(mUri);
        writer.print(prefix);
        writer.print("mProjection=");
        writer.println(Arrays.toString(mProjection));
        writer.print(prefix);
        writer.print("mSelection=");
        writer.println(mSelection);
        writer.print(prefix);
        writer.print("mSelectionArgs=");
        writer.println(Arrays.toString(mSelectionArgs));
        writer.print(prefix);
        writer.print("mSortOrder=");
        writer.println(mSortOrder);
        writer.print(prefix);
        writer.print("mCursor=");
        writer.println(mCursor);
        //writer.print(prefix); writer.print("mContentChanged="); writer.println(mContentChanged);
    }

    private class CursorLoaderContentObserver extends ContentObserver {
        public CursorLoaderContentObserver() {
            super(new Handler());
        }

        @Override
        public boolean deliverSelfNotifications() {
            return true;
        }

        @Override
        public void onChange(boolean selfChange) {
            onContentChanged();
        }
    }
} 

在onCreateView中添加以下代码:

teamListArrayAdapter.notifyDataSetChanged();

暂无
暂无

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

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