リストフラグメントを更新するにはどうすればよいですか? ネットワークからのチュートリアルはありません :( このリストフラグメントをリロードする方法がわかりません。transaktionmanager でリロードしようとしましたが、ActionBar.TabListener と衝突します。これは support.v4 ではありません。loadermanager から新しいデータを取得してリストフラグメントを更新するにはどうすればよいですか?
アクティビティ:
package sk.test;
import android.app.ActionBar;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.app.FragmentTransaction;
import android.support.v4.app.LoaderManager;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import java.util.List;
import java.util.Locale;
import sk.test.frags.TodoFragment;
import sk.test.prefs.EditPreferences;
import sk.test.task.DataListLoader;
import sk.test.xml.Item;
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
private TodoFragment todoFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.action_settings:
startActivity(new Intent(getApplicationContext(), EditPreferences.class));
return true;
case R.id.refresh:
//HERE CODE FOR RELOAD todoFragment.reloadData() ????
return true;
default:
return true;
}
}
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private boolean wantDone = false;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
todoFragment = new TodoFragment();
this.wantDone = position == 0 ? false : true;
Bundle args = new Bundle();
args.putBoolean(TodoFragment.TASK_TYPE, this.wantDone);
todoFragment.setArguments(args);
return todoFragment;
}
@Override
public int getCount() {
return 2;
}
public boolean getWantDone(){
return this.wantDone;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.todotask_planned).toUpperCase(l);
case 1:
return getString(R.string.todotask_done).toUpperCase(l);
}
return null;
}
}
}
リストフラグメント:
package sk.test;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import java.util.List;
import sk.test.adapter.CustomArrayAdapter;
import sk.test.task.DataListLoader;
import sk.test.xml.Item;
/**
* Created by Peter on 29.7.2013.
*/
public class TodoFragment extends ListFragment implements LoaderManager.LoaderCallbacks<List<Item>> {
public static String TASK_TYPE = "taskType";
private static final String XML_SOURCE = "http://******/";
private boolean wantDone = false;
CustomArrayAdapter mAdapter;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i("TODOLIST", "DataListFragment.onActivityCreated");
this.wantDone = getArguments().getBoolean(TASK_TYPE);
// Initially there is no data
setEmptyText("No Data Here");
// Create an empty adapter we will use to display the loaded data.
mAdapter = new CustomArrayAdapter(getActivity());
setListAdapter(mAdapter);
// Start out with a progress indicator.
setListShown(false);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
setHasOptionsMenu(true);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Insert desired behavior here.
Log.i("TODOLIST", "Item clicked: " + id);
}
@Override
public Loader<List<Item>> onCreateLoader(int i, Bundle bundle) {
Log.i("TODOLIST", "DataListFragment.onCreateLoader");
return new DataListLoader(getActivity(), this.wantDone);
}
@Override
public void onLoadFinished(Loader<List<Item>> listLoader, List<Item> items) {
mAdapter.setData(items);
Log.i("TODOLIST", "DataListFragment.onLoadFinished");
// The list should now be shown.
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
@Override
public void onLoaderReset(Loader<List<Item>> listLoader) {
}
public void reloadData(){
//UPDATE LIST.. HOW?
}
}
ローダ:
package sk.test;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v4.content.AsyncTaskLoader;
import android.util.Log;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import sk.test.commons.Commons;
import sk.test.xml.Item;
import sk.test.xml.Response;
/**
* Created by Peter Chovan on 29.7.2013.
*/
public class DataListLoader extends AsyncTaskLoader<List<Item>> {
private List<Item> todoTasks;
private boolean wantDone;
SharedPreferences prefs;
public DataListLoader(Context context, boolean wantDone) {
super(context);
this.wantDone = wantDone;
prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
}
@Override
public List<Item> loadInBackground() {
Log.i("TODOLIST", "DataListLoader.loadInBackground");
String xmlData = getXmlData(prefs.getString("service_url", "http://*****/"));
List<Item> entries = new ArrayList<Item>();
String state = wantDone ? "WANT DONE" : "WANT PLANNED";
if (xmlData != null) {
xmlData = xmlData.replaceAll("<([^/]+?)/>", "<$1> </$1>");
Serializer serializer = new Persister();
try {
Response res = serializer.read(Response.class, xmlData, false);
for (Item i : res.getItems().getItem()) {
if (i.isDone() == wantDone) {
entries.add(i);
}
}
} catch (Exception e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TEST serializer", s.toString());
}
}
} else {
Log.e("TODOLIST DATA", "NULL");
}
return entries;
}
public String getXmlData(String uri) {
try {
URL url = new URL(uri);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setRequestProperty("Accept", "application/xml");
Map<String, String> params = new HashMap<String, String>();
params.put("user", prefs.getString("service_login", "devel"));
params.put("pass", prefs.getString("service_password", "devel"));
params.put("class", "GetList");
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
wr.write(Commons.getRequestData(params)); //add request params
wr.flush();
String xmlData = readStream(con.getInputStream());
wr.close();
con.disconnect();
return xmlData;
} catch (Exception e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "doInBackground" + s.toString());
}
}
return null;
}
private String readStream(InputStream in) {
BufferedReader reader = null;
String result = "";
try {
reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
result += line + "\n";
}
return result;
} catch (IOException e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "ReadStream || " + s.toString());
}
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "ReadStream || " + "Error while closing Reader");
}
}
}
}
return null;
}
/**
* Called when there is new data to deliver to the client. The
* super class will take care of delivering it; the implementation
* here just adds a little more logic.
*/
@Override
public void deliverResult(List<Item> listOfData) {
if (isReset()) {
// An async query came in while the loader is stopped. We
// don't need the result.
if (listOfData != null) {
onReleaseResources(listOfData);
}
}
List<Item> oldApps = listOfData;
todoTasks = listOfData;
if (isStarted()) {
// If the Loader is currently started, we can immediately
// deliver its results.
super.deliverResult(listOfData);
}
// At this point we can release the resources associated with
// 'oldApps' if needed; now that the new result is delivered we
// know that it is no longer in use.
if (oldApps != null) {
onReleaseResources(oldApps);
}
}
/**
* Handles a request to start the Loader.
*/
@Override
protected void onStartLoading() {
if (todoTasks != null) {
// If we currently have a result available, deliver it
// immediately.
deliverResult(todoTasks);
}
if (takeContentChanged() || todoTasks == null) {
// If the data has changed since the last time it was loaded
// or is not currently available, start a load.
forceLoad();
}
}
/**
* Handles a request to stop the Loader.
*/
@Override
protected void onStopLoading() {
// Attempt to cancel the current load task if possible.
cancelLoad();
}
/**
* Handles a request to cancel a load.
*/
@Override
public void onCanceled(List<Item> apps) {
super.onCanceled(apps);
// At this point we can release the resources associated with 'apps'
// if needed.
onReleaseResources(apps);
}
/**
* Handles a request to completely reset the Loader.
*/
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
// At this point we can release the resources associated with 'apps'
// if needed.
if (todoTasks != null) {
onReleaseResources(todoTasks);
todoTasks = null;
}
}
/**
* Helper function to take care of releasing resources associated
* with an actively loaded data set.
*/
protected void onReleaseResources(List<Item> apps) {
}
}