这是我的活动代码:
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();
}
}
我需要的是一个 PagerView,在每个选项卡中都有一个 EnxpandableListView,其中包含来自数据库游标的数据。所有 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)
希望比我更聪明的人可以帮助我发现问题......我做了很多尝试但没有成功。