Reputation: 115
Here is my Activity code :
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();
}
}
What I need is a PagerView with in each tab an EnxpandableListView with data from the database Cursor. All ExpandableListView should stay always expanded. And it should support multi langage (from the menu buttons in ActionBar).
It almost work, but i have strange 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)
Hope somebody wiser than me can help me to spot the problem... I made many tentative without success.
Upvotes: 3
Views: 1163
Reputation: 11
CursorLoader solves this problem. Simple example:
public class MenuCategFragment extends Fragment implements LoaderCallbacks<Cursor>
Add 3 methods and MyCursorLoaderClass.
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
return new MyCursorLoader(getActivity(), db, sectionNumber, currLangId);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.setGroupCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
// TODO Auto-generated method stub
}
static class MyCursorLoader extends CursorLoader{
DataBase db;
int sectionNumber;
long currLangId;
public MyCursorLoader(Context context, DataBase db, int sectionNumber, long currLangId) {
super(context);
this.db = db;
this.sectionNumber = sectionNumber;
this.currLangId = currLangId;
}
@Override
public Cursor loadInBackground() {
return db.getAllCategsInPage(sectionNumber, currLangId);
}
}
After that change this:
ExpandableListAdapter adapter = new MyExpandableListAdapter(**null**, getActivity(), R.layout.categ, fromCategColumns,
toCategViews, R.layout.item, fromItemColumns, toItemViews);
And init CursorLoader:
getActivity().getSupportLoaderManager().initLoader(0, null, this);
Upvotes: 1