これが私のアクティビティコードです:
public class MenuActivity extends FragmentActivity implements
ActionBar.TabListener {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
static DatabaseManager db;
// url to make request
private static String URL = "http://192.168.88.111/MenuManager/mm_menu.php";
static long currLangId;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
final String DB_NAME = "menu"; // the name of our database
final String DB_PATH = "/data/data/com.mypackage.menu/databases/";
File dbFile = new File(DB_PATH + DB_NAME);
Boolean firstLaunch = !dbFile.exists();
db = new DatabaseManager(this);
// new RetreiveJSONAndCacheSQLiteMenu().execute(URL);
if (firstLaunch) {
InputStream is = getResources().openRawResource(R.raw.menu);
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is,
"UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
is.close();
JSONObject jObj = new JSONObject(writer.toString());
parseMenuJSON(jObj);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
currLangId = db.getLangIdFromName(db.LANG_ENGLISH);
// Create the adapter that will return a fragment for each
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// try to hide Navigation bar
// mViewPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
// 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 (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(MenuActivity.this));
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return db.createMenuFromLangs(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
currLangId = db.getLangIdFromName(item.getTitle());
ActionBar actionBar = getActionBar();
actionBar.removeAllTabs();
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(MenuActivity.this));
}
/*
* for (int i = 0; i <
* listView.getExpandableListAdapter().getGroupCount(); i++)
* listView.expandGroup(i);
*/
return true;
}
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
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());
}
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the primary sections of the app.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
Fragment fragment = new MenuCategFragment();
Bundle args = new Bundle();
args.putInt(MenuCategFragment.ARG_SECTION_NUMBER, i);
fragment.setArguments(args);
return fragment;
}
@Override
public int getCount() {
return db.getNumberPages(currLangId);
}
@Override
public CharSequence getPageTitle(int position) {
return db.getPageName(position, currLangId);
}
}
public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {
public MyExpandableListAdapter(Cursor cursor, Context context,
int groupLayout, String[] groupFrom, int[] groupTo,
int childLayout, String[] childFrom, int[] childTo) {
super(context, cursor, groupLayout, groupFrom, groupTo,
childLayout, childFrom, childTo);
}
@Override
protected Cursor getChildrenCursor(Cursor groupCursor) {
return db.getAllItemsInCateg(groupCursor.getLong(0));
}
}
public class MenuCategFragment extends Fragment {
public MenuCategFragment() {
}
public static final String ARG_SECTION_NUMBER = "section_number";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final ExpandableListView listView = new ExpandableListView(
getActivity());
listView.setId(android.R.id.list);
Bundle args = getArguments();
Cursor cursor = db.getAllCategsInPage(
args.getInt(ARG_SECTION_NUMBER), currLangId);
String[] fromCategColumns = { db.CATEG_NAME };
int[] toCategViews = { R.id.categName };
String[] fromItemColumns = { db.ITEM_NAME, db.ITEM_DESC,
db.ITEM_PRICE };
int[] toItemViews = { R.id.itemName, R.id.itemDesc, R.id.itemPrice };
ExpandableListAdapter adapter = new MyExpandableListAdapter(cursor,
getActivity(), R.layout.categ, fromCategColumns,
toCategViews, R.layout.item, fromItemColumns, toItemViews);
listView.setAdapter(adapter);
for (int i = 0; i < adapter.getGroupCount(); i++)
listView.expandGroup(i);
/*
* listView.setOnGroupClickListener(new
* ExpandableListView.OnGroupClickListener() { public boolean
* onGroupClick(ExpandableListView arg0, View itemView, int
* itemPosition, long itemId) { arg0.expandGroup(itemPosition);
* return true; } });
*/
listView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
public void onGroupCollapse(int groupPosition) {
listView.expandGroup(groupPosition);
}
});
return listView;
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
try {
if (!hasFocus) {
Object service = getSystemService("statusbar");
Class<?> statusbarManager = Class
.forName("android.app.StatusBarManager");
Method collapse = statusbarManager.getMethod("collapse");
collapse.setAccessible(true);
collapse.invoke(service);
}
} catch (Exception ex) {
}
}
public class RetreiveJSONAndCacheSQLiteMenu extends
AsyncTask<String, Void, JSONObject> {
InputStream is = null;
JSONObject jObj = null;
String json = "";
protected JSONObject doInBackground(String... urls) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(urls[0]);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
return jObj;
}
protected void onPostExecute(JSONObject json) {
parseMenuJSON(json);
}
}
public void parseMenuJSON(JSONObject json) {
// JSON Node names
final String TAG_LANGS = "langs";
final String TAG_PAGES = "pages";
final String TAG_CATEGORIES = "categories";
final String TAG_ITEMS = "items";
// final String TAG_ID = "id";
final String TAG_NAME = "name";
final String TAG_DESC = "desc";
final String TAG_PRICE = "price";
// final String TAG_PHOTO = "photo";
// JSONArray
JSONArray langs = null;
JSONArray pages = null;
JSONArray categories = null;
JSONArray items = null;
try {
db.voidDatabase();
langs = json.getJSONArray(TAG_LANGS);
long currLangId = 0;
for (int h = 0; h < langs.length(); h++) {
JSONObject lang = langs.getJSONObject(h);
currLangId = db.addLang(lang.getString(TAG_NAME));
pages = lang.getJSONArray(TAG_PAGES);
long currPageId = 0;
for (int i = 0; i < pages.length(); i++) {
JSONObject page = pages.getJSONObject(i);
currPageId = db.addPage(page.getString(TAG_NAME),
currLangId);
categories = page.getJSONArray(TAG_CATEGORIES);
long currCategId = 0;
for (int j = 0; j < categories.length(); j++) {
JSONObject categorie = categories.getJSONObject(j);
currCategId = db.addCateg(
categorie.getString(TAG_NAME), currPageId);
items = categorie.getJSONArray(TAG_ITEMS);
for (int k = 0; k < items.length(); k++) {
JSONObject item = items.getJSONObject(k);
db.addItem(item.getString(TAG_NAME),
item.getString(TAG_DESC),
item.getInt(TAG_PRICE), currCategId);
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
私が必要としているのは、データベース Cursor からのデータを含む EnxpandableListView を各タブに持つ PagerView です。すべての ExpandableListView は常に展開されたままにする必要があります。また、多言語をサポートする必要があります (ActionBar のメニュー ボタンから)。
それはほとんど動作しますが、私は奇妙な FC を持っています:
W/dalvikvm(13556): threadid=1: thread exiting with uncaught exception (group=0x40a641f8)
E/AndroidRuntime(13556): FATAL EXCEPTION: main
E/AndroidRuntime(13556): java.lang.IllegalStateException: this should only be called when the cursor is valid
E/AndroidRuntime(13556): at android.widget.CursorTreeAdapter.getGroupView(CursorTreeAdapter.java:198)
E/AndroidRuntime(13556): at android.widget.ExpandableListConnector.getView(ExpandableListConnector.java:445)
E/AndroidRuntime(13556): at android.widget.AbsListView.obtainView(AbsListView.java:2012)
E/AndroidRuntime(13556): at android.widget.ListView.makeAndAddView(ListView.java:1772)
E/AndroidRuntime(13556): at android.widget.ListView.fillDown(ListView.java:672)
E/AndroidRuntime(13556): at android.widget.ListView.fillSpecific(ListView.java:1330)
E/AndroidRuntime(13556): at android.widget.ListView.layoutChildren(ListView.java:1603)
E/AndroidRuntime(13556): at android.widget.AbsListView.onLayout(AbsListView.java:1863)
E/AndroidRuntime(13556): at android.view.View.layout(View.java:11282)
E/AndroidRuntime(13556): at android.view.ViewGroup.layout(ViewGroup.java:4224)
E/AndroidRuntime(13556): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
E/AndroidRuntime(13556): at android.view.View.layout(View.java:11282)
E/AndroidRuntime(13556): at android.view.ViewGroup.layout(ViewGroup.java:4224)
E/AndroidRuntime(13556): at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1388)
E/AndroidRuntime(13556): at android.view.View.layout(View.java:11282)
E/AndroidRuntime(13556): at android.view.ViewGroup.layout(ViewGroup.java:4224)
E/AndroidRuntime(13556): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
E/AndroidRuntime(13556): at android.view.View.layout(View.java:11282)
E/AndroidRuntime(13556): at android.view.ViewGroup.layout(ViewGroup.java:4224)
E/AndroidRuntime(13556): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
E/AndroidRuntime(13556): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
E/AndroidRuntime(13556): at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
E/AndroidRuntime(13556): at android.view.View.layout(View.java:11282)
E/AndroidRuntime(13556): at android.view.ViewGroup.layout(ViewGroup.java:4224)
E/AndroidRuntime(13556): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
E/AndroidRuntime(13556): at android.view.View.layout(View.java:11282)
E/AndroidRuntime(13556): at android.view.ViewGroup.layout(ViewGroup.java:4224)
E/AndroidRuntime(13556): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1514)
E/AndroidRuntime(13556): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2467)
E/AndroidRuntime(13556): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(13556): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(13556): at android.app.ActivityThread.main(ActivityThread.java:4581)
E/AndroidRuntime(13556): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(13556): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(13556): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
E/AndroidRuntime(13556): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
E/AndroidRuntime(13556): at dalvik.system.NativeStart.main(Native Method)
私よりも賢い誰かが問題を見つけるのを手伝ってくれることを願っています...私は多くの暫定的なものを成功させませんでした。