数据更改时刷新Loader - android

时间:2015-01-09 21:41:27

标签: java android refresh loader android-loadermanager

我使用LoaderManager和CursorLoader使用ContentProvider从我的数据库加载数据。 现在,初始负载很好。我有一个ListView,显示DB中的所有行(只有names-String适配器)。

现在,当我从数据库中添加/删除一行时,我想刷新ListView,以便显示最近的更改。

目前我只是使用方法" restartLoader"重新启动加载程序。无论何时提交更改,但我想询问是否有其他方法可以在不重新启动加载程序的情况下执行此操作。

这是我的活动类代码: package com.silverfix.phony.activities;

import java.util.ArrayList;

import com.silverfix.phony.R;
import com.silverfix.phony.contentprovider.PhonyContentProvider;
import com.silverfix.phony.database.RingtonesTable;

import android.app.Activity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentValues;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.Editable;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

public class RingtonesActivity extends Activity implements LoaderCallbacks<Cursor>{

    private final int PICK_RINGTONE_CODE = 1;
    private final int CURSOR_LOADER_ID = 1;
    private final int EDIT_ID = 1;
    private final int DELETE_ID = 2;
    private String[] ContextCommands;
    private ArrayAdapter<String> adapter;
    private ArrayList<String> ringtones;
    private ListView listview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ringtones);
        listview = (ListView) findViewById(R.id.list);
        Button add = (Button) findViewById(R.id.add_ringtone);
        add.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(i, PICK_RINGTONE_CODE);
            }
        });
        fillData();
    }

    @Override
    protected void onActivityResult(int arg0, int arg1, Intent arg2) {
        super.onActivityResult(arg0, arg1, arg2);
        switch (arg0) {
        case 1: // PICK_RINGTONE_CODE
            if (arg1 == RESULT_OK) {
                Uri ringtoneURI = arg2.getData();
                String[] projection = { MediaStore.MediaColumns.DISPLAY_NAME };
                Cursor cursor = getContentResolver().query(ringtoneURI,
                        projection, null, null, null);
                cursor.moveToFirst();
                int column = cursor
                        .getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
                String displayName = cursor.getString(column);
                addRingtone(ringtoneURI, displayName);
                cursor.close();
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.ringtones, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void fillData() {
        getLoaderManager().initLoader(CURSOR_LOADER_ID, null, this);
        ringtones = new ArrayList<String>();
        adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, ringtones);
        ContextCommands = getResources().getStringArray(R.array.commands);
        listview.setAdapter(adapter);
        listview.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                editRingtone();
            }
        });
        registerForContextMenu(listview);
        listview.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {

            @Override
            public void onCreateContextMenu(ContextMenu menu, View v,
                    ContextMenuInfo menuInfo) {
                if (v.getId()==R.id.list) {
                    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
                    menu.setHeaderTitle(ContextCommands[info.position]);
                    String[] menuItems = getResources().getStringArray(R.array.commands);
                    menu.add(Menu.NONE, EDIT_ID, 0, menuItems[0]);
                    menu.add(Menu.NONE, DELETE_ID, 0, menuItems[1]);
                  }
            }
        });
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch(item.getItemId()) {
        case EDIT_ID:
            editRingtone();
            return true;
        case DELETE_ID:
            String name = adapter.getItem(((AdapterContextMenuInfo) item.getMenuInfo()).position);
            getContentResolver().delete(PhonyContentProvider.RINGTONES_URI, RingtonesTable.COLUMN_NAME
                    + "='" + name + "'", null);
            return true;
        default:
            return super.onContextItemSelected(item);
        }
    }

    private void editRingtone() {
        Intent i = new Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(i, PICK_RINGTONE_CODE);
    }

    private void addRingtone(Uri uri, String name) {
        String[] projection = { RingtonesTable.COLUMN_NAME };
        Cursor cursor = getContentResolver().query(
                PhonyContentProvider.RINGTONES_URI, projection,
                RingtonesTable.COLUMN_NAME + "='"+name+"'", null, null);
        if (cursor.getCount() == 0) {
            ContentValues values = new ContentValues();
            values.put(RingtonesTable.COLUMN_NAME, name);
            values.put(RingtonesTable.COLUMN_URI, uri.toString());
            getContentResolver().insert(PhonyContentProvider.RINGTONES_URI,
                    values);
            getLoaderManager().restartLoader(CURSOR_LOADER_ID, null, this);
        } else {
            Toast.makeText(this, "You already picked that ringtone!",
                    Toast.LENGTH_LONG).show();
            cursor.close();
        }
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        String[] projection = {RingtonesTable.COLUMN_ID, RingtonesTable.COLUMN_NAME, RingtonesTable.COLUMN_URI};
        return new CursorLoader(this, PhonyContentProvider.RINGTONES_URI, projection, null, null, null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        swapCursor(data);
    }

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

    private void swapCursor(Cursor cursor) {
        if(cursor != null) {
            cursor.moveToFirst();
            ringtones.clear();
            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                int column = cursor.getColumnIndex(RingtonesTable.COLUMN_NAME);
                ringtones.add(cursor.getString(column));
            }
            adapter.notifyDataSetChanged();
            cursor.close();
            return;
        }
        ringtones.clear();
        adapter.notifyDataSetChanged();
    }
}

1 个答案:

答案 0 :(得分:2)

由于您已经可以访问加载器,因此您可能不会期望进行太多更改,但另一种实现方法是将光标设置为PhonyContentProvider.RINGTONES_URI作为其通知uri,并在数据库数据发生更改时通知uri

相关方法:
setNotificationUri
notifyChange