I'm new in android programmation. I'm triyng to implement a navigation drawer in wordpress reader declan gao project. I'm getting crazy. He loads a list of wordpress posts and display it with cardview. If I put all necessary in activity_main My navigation drawer appears below cardview posts and I can't interact with it. If I try to put it in TabLayoutFragment i have a lot of errors!!!
Is there someone who can help me to insert navigation drawer in the right place!!!
Than you so much!!!
This is MainActivity.java
public class MainActivity extends AppCompatActivity implements
RecyclerViewFragment.PostListListener, PostFragment.PostListener,
TabLayoutFragment.TabLayoutListener, SearchResultFragment.SearchResultListener
{
private static final String TAG = MainActivity.class.getSimpleName();
public static final String TAB_LAYOUT_FRAGMENT_TAG = "TabLayoutFragment";
public static final String POST_FRAGMENT_TAG = "PostFragment";
private FragmentManager fm = null;
private TabLayoutFragment tlf;
private PostFragment pf;
private SearchResultFragment srf;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
fm = getSupportFragmentManager();
// Setup fragments
tlf = new TabLayoutFragment();
pf = new PostFragment();
srf = new SearchResultFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.add(android.R.id.content, pf, POST_FRAGMENT_TAG);
ft.add(android.R.id.content, tlf, TAB_LAYOUT_FRAGMENT_TAG);
ft.hide(pf);
ft.commit();
}
/**
* Invoked when a post in the list is selected
*
* #param post Selected Post object
*/
#Override
public void onPostSelected(Post post, boolean isSearch) {
// Find the fragment in order to set it up later
pf = (PostFragment) getSupportFragmentManager().findFragmentByTag(POST_FRAGMENT_TAG);
// Set necessary arguments
Bundle args = new Bundle();
args.putInt("id", post.getId());
args.putString("title", post.getTitle());
args.putString("date", post.getDate());
args.putString("author", post.getAuthor());
args.putString("content", post.getContent());
args.putString("url", post.getUrl());
//args.putString("thumbnailUrl", post.getThumbnailUrl());
args.putString("featuredImage", post.getFeaturedImageUrl());
// Configure PostFragment to display the right post
pf.setUIArguments(args);
// Show the fragment
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right,
android.R.anim.slide_in_left, android.R.anim.slide_out_right);
if (!isSearch) { // Hide TabLayoutFragment if this is not search result
ft.hide(tlf);
} else { // Otherwise, hide the search result, ie. SearchResultFragment.
ft.hide(srf);
}
ft.show(pf);
ft.addToBackStack(null);
ft.commit();
}
/**
* Invoked when a search query is submitted
*
* #param query Selected Post object
*/
#Override
public void onSearchSubmitted(String query) {
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right,
android.R.anim.slide_in_left, android.R.anim.slide_out_right);
// Send query to fragment using factory method
srf = SearchResultFragment.newInstance(query);
ft.add(android.R.id.content, srf);
ft.hide(tlf);
ft.addToBackStack(null);
ft.commit();
}
/**
* Invoked when comment menu is selected
*
* #param id ID of the article, assigned by WordPress
*/
#Override
public void onCommentSelected(int id) {
Bundle args = new Bundle();
args.putInt("id", id);
// Setup CommentFragment to display the right comments page
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right,
android.R.anim.slide_in_left, android.R.anim.slide_out_right);
ft.hide(pf);
ft.addToBackStack(null);
ft.commit();
}
/**
* Intercept back button event, reset ActionBar if necessary
*/
#Override
public void onBackPressed() {
resetActionBarIfApplicable();
super.onBackPressed();
}
/**
* Simulate a back button press when home is selected
*/
#Override
public void onHomePressed() {
resetActionBarIfApplicable();
fm.popBackStack();
}
/**
* Reset TabLayoutFragment's ActionBar if necessary
*/
private void resetActionBarIfApplicable() {
Log.d(TAG, "SearchResultFragment is visible: " + srf.isHidden());
if (srf.isVisible()) {
tlf.resetActionBar();
}
}
// Commented out coz we will let fragments handle their own Options Menus
//#Override
//public boolean onCreateOptionsMenu(Menu menu) {
// // Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.menu_main, menu);
// return true;
//}
}
This is activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--<android.support.v7.widget.Toolbar-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:background="#color/colorPrimary"-->
<!--android:theme="#style/ThemeOverlay.AppCompat.Dark"-->
<!--android:id="#+id/toolbar">-->
<!--</android.support.v7.widget.Toolbar>-->
<!--<FrameLayout-->
<!--android:id="#+id/container"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent">-->
<!--</FrameLayout>-->
This is TabLayoutFragment.java
/**
* Fragment to display TabLayout and ViewPager.
* Activities that contain this fragment must implement the
* {#link TabLayoutFragment.TabLayoutListener} interface
* to handle interaction events.
*/
public class TabLayoutFragment extends Fragment implements SearchView.OnQueryTextListener {
private static final String TAG = "TabLayoutFragment";
private ProgressDialog mProgressDialog;
private TabLayout mTabLayout;
private ViewPager mViewPager;
private Toolbar toolbar;
private SearchView searchView;
private MenuItem searchMenuItem;
// List of all categories
protected static ArrayList<Category> categories = null;
private TabLayoutListener mListener;
public TabLayoutFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Stops onDestroy() and onCreate() being called when the parent
// activity is destroyed/recreated on configuration change
setRetainInstance(true);
// Display a search menu
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_tab_layout, container, false);
toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
((MainActivity)getActivity()).setSupportActionBar(toolbar);
mTabLayout = (TabLayout) rootView.findViewById(R.id.tab_layout);
mViewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
// Preload 1 page to either side of the current page
mViewPager.setOffscreenPageLimit(1);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
loadCategories();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Log.d(TAG, "onCreateOptionsMenu()");
inflater.inflate(R.menu.menu_main, menu);
// Create expandable & collapsible SearchView
SearchManager searchManager = (SearchManager)
getActivity().getSystemService(Context.SEARCH_SERVICE);
searchMenuItem = menu.findItem(R.id.action_search);
searchView = (SearchView) searchMenuItem.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
searchView.setIconifiedByDefault(false); // Expanded by default
//searchView.requestFocus();
searchView.setQueryHint(getString(R.string.search_hint));
searchView.setOnQueryTextListener(this);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_search) {
searchView.requestFocus();
}
return true;
}
/**
* Reset the ActionBar to show proper menu and collapse SearchView
*/
protected void resetActionBar() {
((MainActivity)getActivity()).setSupportActionBar(toolbar);
searchMenuItem.collapseActionView();
}
/**
* Download categories and create tabs
*/
private void loadCategories() {
// Display a progress dialog
mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.setMessage(getString(R.string.loading_categories));
// User cannot dismiss it by touching outside the dialog
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show();
// Make a request to get categories
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, Config.CATEGORY_URL,
null,
new Response.Listener<JSONObject>() {
// Request succeeded
#Override
public void onResponse(JSONObject jsonObject) {
mProgressDialog.dismiss();
// Get categories from JSON data
categories = JSONParser.parseCategories(jsonObject);
RecyclerViewFragmentPagerAdaptor adaptor = new
RecyclerViewFragmentPagerAdaptor(getChildFragmentManager(), categories);
mViewPager.setAdapter(adaptor);
mTabLayout.setupWithViewPager(mViewPager);
}
},
// Request failed
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.d(TAG, "----- Volley Error -----");
mProgressDialog.dismiss();
// Show an INDEFINITE Snackbar. New in design support lib v22.2.1.
Snackbar.make(mTabLayout, R.string.error_load_categories,
Snackbar.LENGTH_INDEFINITE).setAction(R.string.action_retry,
new View.OnClickListener() {
#Override
public void onClick(View v) {
loadCategories();
}
}).show();
}
});
// Add the request to request queue
AppController.getInstance().addToRequestQueue(request);
}
#Override
public boolean onQueryTextSubmit(String query) {
searchView.clearFocus(); // Hide soft keyboard
mListener.onSearchSubmitted(query); // Deal with fragment transaction on MainActivity
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (TabLayoutListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() +
"must implement PostListListener");
}
}
// Interface used to communicate with MainActivity
public interface TabLayoutListener {
void onSearchSubmitted(String query);
}
}
This is FragmentTabLayout.xml
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="me.declangao.wordpressreader.app.TabLayoutFragment">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll|enterAlways"
/>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:tabGravity="fill"
style="#style/CustomTabLayout"/>
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
This is RecyclerViewFragment.java
/**
* Fragment to display a RecyclerView.
* Activities that contain this fragment must implement the
* {#link RecyclerViewFragment.PostListListener} interface
* to handle interaction events.
*/
public class RecyclerViewFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = "RecyclerViewFragment";
protected static final String CAT_ID = "id";
protected static final String QUERY = "query";
private SwipeRefreshLayout mSwipeRefreshLayout;
private RecyclerView mRecyclerView;
private MyRecyclerViewAdaptor mAdaptor;
private LinearLayoutManager mLayoutManager;
// Widget to show user a loading message
private TextView mLoadingView;
// List of all posts in the ListView
private ArrayList<Post> postList = new ArrayList<>();
// A flag to keep track if the app is currently loading new posts
private boolean isLoading = false;
private int mPage = 1; // Page number
private int mCatId; // Category ID
private int mPreviousPostNum = 0; // Number of posts in the list
private int mPostNum; // Number of posts in the "new" list
private String mQuery = ""; // Query string used for search result
// Flag to determine if current fragment is used to show search result
private boolean isSearch = false;
// Keep track of the list items
private int mPastVisibleItems;
private int mVisibleItemCount;
private PostListListener mListener;
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param id ID of the category.
* #return A new instance of RecyclerViewFragment.
*/
public static RecyclerViewFragment newInstance(int id) {
RecyclerViewFragment fragment = new RecyclerViewFragment();
Bundle args = new Bundle();
args.putInt(CAT_ID, id);
fragment.setArguments(args);
return fragment;
}
/**
* Use this factory method to create a new instance of this fragment
* using the provided parameters to display search result.
*
* #param query search query.
* #return A new instance of RecyclerViewFragment.
*/
public static RecyclerViewFragment newInstance(String query) {
RecyclerViewFragment fragment = new RecyclerViewFragment();
Bundle args = new Bundle();
args.putString(QUERY, query);
fragment.setArguments(args);
return fragment;
}
public RecyclerViewFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mCatId = getArguments().getInt(CAT_ID, -1);
mQuery = getArguments().getString(QUERY, "");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_recycler_view, container, false);
// Pull to refresh layout
mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh_layout);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
mLoadingView = (TextView) rootView.findViewById(R.id.text_view_loading);
mLayoutManager = new LinearLayoutManager(getActivity());
// Pull to refresh listener
mSwipeRefreshLayout.setOnRefreshListener(this);
// RecyclerView adaptor for Post object
mAdaptor = new MyRecyclerViewAdaptor(postList, new MyRecyclerViewAdaptor.OnItemClickListener() {
#Override
public void onItemClick(Post post) {
mListener.onPostSelected(post, isSearch);
}
});
mRecyclerView.setHasFixedSize(true); // Every row in the list has the same size
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdaptor);
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
// Automatically load new posts if end of the list is reached
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
//super.onScrolled(recyclerView, dx, dy);
mVisibleItemCount = mLayoutManager.getChildCount();
mPastVisibleItems = mLayoutManager.findFirstVisibleItemPosition();
int totalItemCount = mLayoutManager.getItemCount();
if (mPostNum > mPreviousPostNum && !postList.isEmpty() && mVisibleItemCount != 0 &&
totalItemCount > mVisibleItemCount && !isLoading &&
(mVisibleItemCount + mPastVisibleItems) >= totalItemCount) {
loadNextPage();
// Update post number
mPreviousPostNum = mPostNum;
}
}
});
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
loadFirstPage();
}
/**
* Load the first page of a category
*/
public void loadFirstPage(){
mPage = 1; // Reset page number
if (postList.isEmpty()) {
showLoadingView();
// Reset post number to 0
mPreviousPostNum = 0;
loadPosts(mPage, false);
} else {
hideLoadingView();
}
}
/**
* Load the next page of a category
*/
public void loadNextPage(){
mPage ++;
loadPosts(mPage, true);
}
/**
* Load posts from a specific page number
*
* #param page Page number
* #param showLoadingMsg Flag to determine whether to show Toast loading msg to inform the user
*/
private void loadPosts(int page, final boolean showLoadingMsg) {
Log.d(TAG, "----------------- Loading category id " + mCatId +
", page " + String.valueOf(page));
isLoading = true;
if (showLoadingMsg) {
Toast.makeText(getActivity(), getString(R.string.loading_articles),
Toast.LENGTH_LONG).show();
}
// Construct the proper API Url
String url;
if (!mQuery.isEmpty()) { // Not empty mQuery means this list is for search result.
isSearch = true;
url = Config.BASE_URL + "?json=get_search_results&search=" + mQuery +
"&page=" + String.valueOf(page);
} else { // Empty mQuery means normal list of posts
isSearch = false;
if (mCatId == 0) { // The "All" tab
url = Config.BASE_URL + "?json=get_posts&page=" + String.valueOf(page);
} else { // Everything else
isSearch = false;
url = Config.BASE_URL + "?json=get_category_posts&category_id=" + String.valueOf(mCatId)
+ "&page=" + String.valueOf(page);
}
}
Log.d(TAG, url);
// Request post JSON
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
mSwipeRefreshLayout.setRefreshing(false); // Stop when done
// Parse JSON data
postList.addAll(JSONParser.parsePosts(jsonObject));
// A temporary workaround to avoid downloading duplicate posts in some
// rare circumstances by converting ArrayList to a LinkedHashSet without
// losing its order
Set<Post> set = new LinkedHashSet<>(postList);
postList.clear();
postList.addAll(new ArrayList<>(set));
mPostNum = postList.size(); // The newest post number
Log.d(TAG, "Number of posts: " + mPostNum);
mAdaptor.notifyDataSetChanged(); // Display the list
// Set ListView position
if (RecyclerViewFragment.this.mPage != 1) {
// Move the article list up by one row
// We don't actually need to add 1 here since position starts at 0
mLayoutManager.scrollToPosition(mPastVisibleItems + mVisibleItemCount);
}
// Loading finished. Set flag to false
isLoading = false;
hideLoadingView();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
isLoading = false;
hideLoadingView();
mSwipeRefreshLayout.setRefreshing(false);
volleyError.printStackTrace();
Log.d(TAG, "----- Error: " + volleyError.getMessage());
// Show a Snackbar with a retry button
Snackbar.make(mRecyclerView, R.string.error_load_posts,
Snackbar.LENGTH_LONG).setAction(R.string.action_retry,
new View.OnClickListener() {
#Override
public void onClick(View v) {
//loadFirstPage();
loadPosts(mPage, true);
}
}).show();
}
});
// Set timeout to 10 seconds instead of the default value 5 since my
// crappy server is quite slow
request.setRetryPolicy(new DefaultRetryPolicy(10000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
// Add request to request queue
AppController.getInstance().addToRequestQueue(request, TAG);
}
#Override
public void onRefresh() {
// Clear the list
postList.clear();
mAdaptor.notifyDataSetChanged();
loadFirstPage();
}
/**
* Show the loading view and hide the list
*/
private void showLoadingView() {
mRecyclerView.setVisibility(View.INVISIBLE);
mLoadingView.setVisibility(View.VISIBLE);
}
/**
* Hide the loading view and show the list
*/
private void hideLoadingView() {
mLoadingView.setVisibility(View.INVISIBLE);
mRecyclerView.setVisibility(View.VISIBLE);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (PostListListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() +
"must implement PostListListener");
}
}
// Interface used to communicate with MainActivity
public interface PostListListener {
void onPostSelected(Post post, boolean isSearch);
}
}
This is fragment_recyclerview.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="me.declangao.wordpressreader.app.RecyclerViewFragment">
<!-- Article list -->
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/swipe_refresh_layout" >
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:id="#+id/recycler_view" />
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/text_view_loading"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center"
android:text="#string/loading_articles"/>
Related
Tried many ways, but none works perfectly. I want to get main activity from the fragments set up in a navigation view.
I tried
#Override
public void onBackPressed() {
startActivity(new Intent(this, MainActivity.class));
}
but it won't function properly. I want it like when I'm in a fragmented activity it returns back to main and while clicking back again it quits (I already did this), help me out with when back pressed get back to main activity
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE = 1000 ;
private static final String TAG = "MainActivity";
private AdView mAdView;
ImageView imageView;
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
List<Item> items;
CustomAdapter adapter;
private long backpressedtime;
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case PERMISSION_REQUEST_CODE:
{
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this,"Permission Denied", Toast.LENGTH_SHORT).show();
}
break;
}
}
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String str="Click on Wallpaper to set Wallpaper";
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
imageView=(ImageView)findViewById(R.id.imageView);
mDrawerLayout=(DrawerLayout) findViewById(R.id.dl);
mToggle=new ActionBarDrawerToggle(this,mDrawerLayout,R.string.open,R.string.close);
mDrawerLayout.addDrawerListener(mToggle);
mToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
NavigationView navigationView = (NavigationView) findViewById(R.id.Navigation_v);
setupDrawerContent(navigationView);
ActionBar actionBar = getSupportActionBar();
recyclerView =(RecyclerView)findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
imageView=(ImageView)findViewById(R.id.imageView);
initItem();
//start service and play music
startService(new Intent(MainActivity.this, SoundService.class));
}
public void toast(View v) {
Toast.makeText(MainActivity.this, "Wallpaper Set", Toast.LENGTH_LONG).show();
}
private void initItem() {
items = new ArrayList<>();
items.add(new Item(0,"Wide","https://images8.alphacoders.com/532/thumb-1920-532407.jpg"));
items.add(new Item(1, "Wide","https://images5.alphacoders.com/394/thumb-1920-394511.jpg"));
items.add(new Item(1,"Wide","https://images5.alphacoders.com/408/thumb-1920-408539.jpg"));
adapter = new CustomAdapter(this,items);
recyclerView.setAdapter(adapter);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
protected void onDestroy() {
//stop service and stop music
stopService(new Intent(MainActivity.this, SoundService.class));
super.onDestroy();
}
public void selectItemDrawer(MenuItem menuItem){
Fragment myFragment = null;
Class fragmentClass;
switch (menuItem.getItemId()) {
case R.id.walkthrough:
fragmentClass = Walkthrough.class;
break;
case R.id.info:
fragmentClass = About.class;
break;
default:
fragmentClass = Walkthrough.class;
}
try {
myFragment = (Fragment) fragmentClass.newInstance();
}
catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flcontent,myFragment).commit();
setTitle(menuItem.getTitle());
mDrawerLayout.closeDrawers();
}
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
selectItemDrawer(item);
return true;
}
});
}
#Override
public void onBackPressed() {
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("Are you sure you want to exit?");
builder.setCancelable(true);
builder.setNegativeButton("No Stay ;-)", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
builder.setPositiveButton("Yes :'-(", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
Walkthrough.java
public class Walkthrough extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public Walkthrough() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment Walkthrough.
*/
// TODO: Rename and change types and number of parameters
public static Walkthrough newInstance(String param1, String param2) {
Walkthrough fragment = new Walkthrough();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_walkthrough, container, false);
WebView webView = (WebView)v.findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true); //enable javascript
webView.setWebViewClient(new WebViewClient()); //important to open url in your app
webView.loadUrl("http://ign.com/wikis/the-last-of-us/Prologue");
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
If you want to go back to the MainActivity onBack click of WalkthroughFragment then while commit your fragment add it to BackStack using this method:
FragmentTransaction addToBackStack (String name)
This method will do the below operation:
Will Add this transaction to the back stack. This means that the transaction will be remembered after it is committed, and will reverse its operation when later popped off the stack.
You can use it like that
FragmentTransaction ftx = getFragmentManager().beginTransaction();
ftx.replace(R.id.my_container_frame, fragment);
ftx.addToBackStack(null);
ftx.commit();
Alternatively you include all the function invocations on a single line
getSupportFragmentManager().beginTransaction().replace('Your Fragment Container ID', new 'Fragment Class Name').addToBackStack(null).commit();
Cheers!
I need some help with my little android project.
So, i have to collect data in a thread. I've created a thread and handler to send message to the ui thread. Which works in a simple activity.
But here comes the problem: I want to display the data in different ways: "real time data" = in a textview, data in a chart, and previous (historycal data).
So for this, i created a tabbed activity with 3 fragments (one for real time data, one for a chart, one for the historycal chart). But all of these fragments needs the same data from my thread (except the last fragment which needs the last 5-10 i donw know how many data).
So where shall i start to read? What options i have? Shall i use the same handlers in these fragments? If yes how can i reference them? Or i have to make I am a bit confused, please help me.
Here is the "main" tabbed activity (please note that the messages from the thread are dummy data yet) :
public class ThermoMeasurementActivity extends AppCompatActivity {
private final int SENSOR_POS_BOTTOM = 0x00;
private final int SENSOR_POS_TOP = 0xFF;
private Handler handler;
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link 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}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_thermo_measurement);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
handler = new Handler() {
public void handleMessage(Message msg) {
String aResponse = msg.getData().getString("message");
if ((null != aResponse)) {
Log.d("mytag", "Temp = " + aResponse);
}
else
{
Log.d("mytag", "Temp = " + aResponse);
}
}
};
ThermoReaderTask thermoReaderTask = new ThermoReaderTask(handler, SENSOR_POS_BOTTOM, 1000);
thermoReaderTask.start();
ThermoReaderTask thermoReaderTask2 = new ThermoReaderTask(handler, SENSOR_POS_TOP, 1000);
thermoReaderTask2.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_thermo_measurement, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
switch (position) {
case 0:
ThermoMeter tabThermoMeter = new ThermoMeter();
return tabThermoMeter;
case 1:
RealTimeThermoChart rtThermoChart = new RealTimeThermoChart();
return rtThermoChart;
case 2:
HistoryChart historyChart = new HistoryChart();
return historyChart;
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Thermo Meter";
case 1:
return "Real Time Chart";
case 2:
return "History Chart";
}
return null;
}
}
public class ThermoReaderTask extends Thread
{
private Handler handler;
int looptime;
int sensorPos;
ThermoReaderTask(Handler handler, int sensorPos, int looptime)
{
this.handler = handler;
this.looptime = looptime;
this.sensorPos = sensorPos;
}
#Override
public void run() {
try {
while(true) {
String msg = "error";
if(sensorPos == SENSOR_POS_BOTTOM)
{
msg = "BOTTOM TEMP = 28";
}else if(sensorPos == SENSOR_POS_TOP)
{
msg = "TOP TEMP = 28";
}
Message msgObj = handler.obtainMessage();
Bundle b = new Bundle();
b.putString("message", msg);
msgObj.setData(b);
handler.sendMessage(msgObj);
sleep(looptime);
}
} catch (Throwable t) {
}
}
}
}
And here is one of the fragments (please not that the commented parts are just attempts):
public class ThermoMeter extends Fragment implements
CompoundButton.OnCheckedChangeListener {
private int TEMP_MODE_TOP = 0x00;
private int TEMP_MODE_BOTTOM = 0x00;
private final int SENSOR_POS_BOTTOM = 0x00;
private final int SENSOR_POS_TOP = 0xFF;
private ImageView imgvUnitTop;
private ImageView imgvUnitBottom;
private ToggleButton tbTempTop;
private ToggleButton tbTempBottom;
private Handler handler;
private TextView tvTempTop;
private TextView tvTempBottom;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1thermometer, container, false);
imgvUnitTop = (ImageView)rootView.findViewById(R.id.imgvTop);
tbTempTop = (ToggleButton)rootView.findViewById(R.id.tbTempTop);
imgvUnitBottom = (ImageView)rootView.findViewById(R.id.imgvBottom);
tbTempBottom = (ToggleButton)rootView.findViewById(R.id.tbTempBottom);
tbTempBottom.setOnCheckedChangeListener(this);
tbTempTop.setOnCheckedChangeListener(this);
tvTempTop = (TextView)rootView.findViewById(R.id.tvTempTop);
tvTempBottom = (TextView)rootView.findViewById(R.id.tvTempBottom);
/*handler = new Handler() {
public void handleMessage(Message msg) {
String aResponse = msg.getData().getString("message");
if ((null != aResponse)) {
Log.d("mytag", "Temp = " + aResponse);
}
else
{
Log.d("mytag", "Temp = " + aResponse);
}
}
};*/
/* ThermoReaderTask thermoReaderTask = new ThermoReaderTask(handler, SENSOR_POS_BOTTOM, 1000);
thermoReaderTask.start();
ThermoReaderTask thermoReaderTask2 = new ThermoReaderTask(handler, SENSOR_POS_TOP, 1000);
thermoReaderTask2.start();*/
return rootView;
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (buttonView.getId() == R.id.tbTempTop) {
if(isChecked)
{
TEMP_MODE_TOP = 0x00;
imgvUnitTop.setImageResource(R.drawable.celsius);
}else
{
TEMP_MODE_TOP = 0xFF;
imgvUnitTop.setImageResource(R.drawable.fahrenheit);
}
}
else if(buttonView.getId() == R.id.tbTempBottom){
if(isChecked)
{
TEMP_MODE_BOTTOM = 0x00;
imgvUnitBottom.setImageResource(R.drawable.celsius);
}else
{
TEMP_MODE_BOTTOM = 0xFF;
imgvUnitBottom.setImageResource(R.drawable.fahrenheit);
}
}
}
}
Could you please give me some links, tutorials, hints anything?
I want to make an App, which has a NavigationView and some fragments. I have no problem to display the different fragments and to navigate inside the application. But I did not manage to implement buttons inside my fragments.
Nothing happens when I click on the button. However I don't have any error.I have searched on Internet and I really don't understand why it doesn't work.I used the same method as in "classic" activity. I guess there is a problem withb.setOnClickListener(this). I pasted my code. I hope one of you will see my error. Thanks a lot for reading.
Accueil.java (mainActivity):
public class Accueil extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,
HomeFragment.OnFragmentInteractionListener,Settings_accountFragment.OnFragmentInteractionListener {
NavigationView navigationView;
private FragmentTransaction fragmentTransaction;
private FragmentManager fragmentManager;
private static UserLocalStore userLocalStore;
private static User user;
public Intent login;
//private TextView eventName,eventPlace,eventSchedule;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_accueil);
userLocalStore=new UserLocalStore(this);
login=new Intent(this,LoginActivity.class);
navigationView = (NavigationView) findViewById(R.id.nav_view);
fragmentManager = getFragmentManager();
Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(myToolbar);
getSupportActionBar();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, myToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
loadSelection(0);
}
private void loadSelection(int i){
switch (i){
case 0:
HomeFragment homeFragment = new HomeFragment();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragmentholder,homeFragment);
fragmentTransaction.commit();
break;
case 1:
Settings_accountFragment settings_account = new Settings_accountFragment();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragmentholder,settings_account);
fragmentTransaction.commit();
break;
default:
break;
}
}
#Override
protected void onStop() {
//userLocalStore.clearUserData();
userLocalStore.setUserLoggedIn(false);
userLocalStore.deleteCurrentUser();
super.onStop();
}
#Override
protected void onStart() {
super.onStart();
if(userLocalStore.getUserLoggedIn()) {
user=userLocalStore.getLoggedInUser(userLocalStore.getCurrentUser());
int i=0;
//How to change elements in the header programatically
View headerView = navigationView.getHeaderView(0);
TextView emailText = (TextView) headerView.findViewById(R.id.mail_header);
emailText.setText(user.getMail());
}
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_acc) {
// Handle the camera action
loadSelection(0);
} else if (id == R.id.nav_param) {
} else if (id == R.id.nav_param_compte) {
loadSelection(1);
} else if(id==R.id.logOut){
userLocalStore.setUserLoggedIn(false);
userLocalStore.deleteCurrentUser();
startActivity(login);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//getMenuInflater().inflate(R.menu.menu_calendar, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
return super.onOptionsItemSelected(item);
}
public static User getUser() {
return user;
}
public static UserLocalStore getUserLocalStore() {
return userLocalStore;
}
#Override
public void onFragmentInteraction(Uri uri) {
}
/*public void setEventNameText(String name) {
this.eventName.setText(name);
}
public void setEventPlaceText(String place) {
this.eventName.setText(place);
}
public void setEventScheduleText(String schedule) {
this.eventName.setText(schedule);
}*/
/*#Override
public Dialog onCreateDialog (int id) {
Dialog box = null;
switch(id) {
// Quand on appelle avec l'identifiant de la boîte normale
case ID_NORMAL_DIALOG:
box = new Dialog(this);
box.setTitle("Je viens tout juste de naître.");
break;
// Quand on appelle avec l'identifiant de la boîte qui s'énerve
case ID_ENERVEE_DIALOG:
box = new Dialog(this);
box.setTitle("ET MOI ALORS ???");
}
return box;
}
#Override
public void onPrepareDialog (int id, Dialog box) {
if(id == ID_NORMAL_DIALOG && compteur > 1)
box.setTitle("On est au " + compteur + "ème lancement !");
//On ne s'intéresse pas au cas où l'identifiant vaut 1, puisque cette boîte affiche le même texte à chaque lancement
}*/
}
Settings_accountFragment.java :
public class Settings_accountFragment extends Fragment implements View.OnClickListener {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
Button b;
View v;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public Settings_accountFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment Settings_accountFragment.
*/
// TODO: Rename and change types and number of parameters
public static Settings_accountFragment newInstance(String param1, String param2) {
Settings_accountFragment fragment = new Settings_accountFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
v=inflater.inflate(R.layout.fragment_settings_account, container, false);
b=(Button)v.findViewById(R.id.button);
b.setOnClickListener(this);
return inflater.inflate(R.layout.fragment_settings_account, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button:
Log.d("coucou","true");
break;
}
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
fragment_settings_account.xml:
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/parametre_compte"
android:background="#color/grey"
android:gravity="center"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:layout_gravity="center_horizontal" />
</FrameLayout>
You are not showing the correct view that has the button you set the click listener on because you are inflating the view again and returning it in onCreateView().
Replace
return inflater.inflate(R.layout.fragment_settings_account, container, false);
With
return v;
So that you return the view you already inflated.
In Settings_accountFragment:onCreateView you are inflating the view twice. Remove the second inflate code and just return v;
v=inflater.inflate(R.layout.fragment_settings_account, container, false);
b=(Button)v.findViewById(R.id.button);
b.setOnClickListener(this);
return v;
Also, a side note - it's not common to use '_' in Java class names. SettingsAccountFragment is a better than Settings_accountFragment
In Android if I start new Activity B from within activity A, Android will automatically save all the state of Activity A. So when I click back button on the device in Activity B, A will be restored to the state when I had started Activity B (for example: Spinners, ListView and Toggle Buttons all are in their previous positions).
BUT when I click the back button in action bar activity A starts fresh with no stored state.
Is there any way to make this back button similar to the device's back or I have to use SharedPreferences and store every thing myself?
(api 8 and above for my app)
In one of the fragments in my app I have a ListView which is one of the fragments that needs to be in the same state when coming back from the next page. I have added the code below.
If any other part is needed please tell me and I will add the code.
The main activity code:
private ProgressDialog progress;
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a {#link 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;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(Farsi.Convert(getString(R.string.app_name_farsi)));
setContentView(R.layout.activity_main);
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
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) {
// Handle action bar item clicks here. The action bar will automatically handle clicks on the Home/Up button, so long as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent intent=new Intent(MainActivity.this, AboutActivity.class);
startActivity(intent);
}
return super.onOptionsItemSelected(item);
}
#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) {
}
Here is the code to my List Fragment:
public class SearchResultListFragment extends Fragment{
Pagination pagination;
boolean loadingMore = false;
ListView list;
TextView text1;
TextView text2;
TextView text3;
TextView text4;
TextView text5;
Button Btngetdata;
private static String url = "https://www.....com/api/property/search";
private static int currentFirstVisibleItem;
public SearchResultArrayListAdaptor adapter ;
LinearLayout linlaHeaderProgress;
JSONArray jsonArray = null;
JSONParse fetchclass = null;
public SearchResultListFragment() {
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
linlaHeaderProgress = (LinearLayout) getActivity().findViewById(R.id.linlaHeaderProgress);
ArrayAdapter<PropertyObject> aa =(ArrayAdapter<PropertyObject>) list.getAdapter();
if (aa!= null){
aa.clear();
aa.notifyDataSetChanged();
}
list.setOnItemClickListener((OnItemClickListener) getActivity());
adapter = new SearchResultArrayListAdaptor(getActivity(), R.layout.list_view_items, new ArrayList<PropertyObject>());
list.setAdapter(adapter);
pagination = new Pagination(0,15);
fetchclass = new JSONParse(getActivity());
fetchclass.execute(url);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_search_result_list, container, false);
list=(ListView)rootView.findViewById(R.id.listViewSearchResult);
list.setOnScrollListener(
new OnScrollListener(){
private int currentVisibleItemCount;
private int currentTotalItemCount;
private int currentScrollState;
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.currentScrollState = scrollState;
this.isScrollCompleted();
}
private void isScrollCompleted() {
if (currentFirstVisibleItem + currentVisibleItemCount >= currentTotalItemCount) {
if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) {
if(fetchclass!=null) {
pagination = new Pagination(this.currentTotalItemCount,15);
if(!(fetchclass.getStatus()== AsyncTask.Status.RUNNING)) {
fetchclass= new JSONParse(getActivity());
fetchclass.execute(url);
}
}
else {
fetchclass = new JSONParse(getActivity());
fetchclass.execute(url);
}
}
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
currentFirstVisibleItem = firstVisibleItem;
this.currentVisibleItemCount = visibleItemCount;
this.currentTotalItemCount = totalItemCount;
}
});
return rootView;
}
//*********************************** inner class
public class JSONParse extends AsyncTask<String, String, JSONObject> {
Context mContext;
int checkBoxRooms;
public JSONParse(Context context){
mContext = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
linlaHeaderProgress.setVisibility(View.VISIBLE);
}
#Override
protected JSONObject doInBackground(String... args) {
JSONObject json = null;
PropertyFilter searchFilter = SearchFilterManager.initializePropertyFilter(new PropertyFilter(), getArguments());
getActivity().setProgressBarIndeterminateVisibility(true);
JSONParserForSearch jParser = new JSONParserForSearch();
json = jParser.getJSONFromUrl(url, searchFilter, pagination);
return json;
}
#Override
protected void onPostExecute(JSONObject json) {
// SHOW THE SPINNER WHILE LOADING FEEDS
getActivity().setProgressBarIndeterminateVisibility(false);
PropertyObject propertyObject;
try {
jsonArray = json.getJSONArray("PropertyListings");
if (jsonArray == null || jsonArray.length()<1){
// list.setEmptyView(getActivity().findViewById(R.id.txtNoResult));
}
else {
for(int i = 0; i < jsonArray.length(); i++){
JSONObject c = jsonArray.getJSONObject(i);
propertyObject = new Gson().fromJson(c.toString(), new PropertyObject().getClass());
adapter.add(propertyObject);
adapter.notifyDataSetChanged();
}
}
// CHANGE THE LOADINGMORE STATUS TO PERMIT FETCHING MORE DATA
loadingMore = false;
// HIDE THE SPINNER AFTER LOADING FEEDS
linlaHeaderProgress.setVisibility(View.GONE);
}
catch (JSONException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
My layout XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
<ListView
android:id="#+id/listViewSearchResult"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="2"
>
</ListView>
<LinearLayout
android:id="#+id/linlaHeaderProgress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
>
My Adapter is ArrayAdapter.
I have implemented isEmpty and getCount too.
My Activity For List:
public class SearchResultListActivity extends ActionBarActivity implements OnItemClickListener{
static PropertyObject selectedPropertyObject;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
Bundle bundle=new Bundle();
bundle.putInt("intentionOfOwner", intent.getIntExtra("intentionOfOwner",0));
SearchResultListFragment fragobj=new SearchResultListFragment();
fragobj.setArguments(bundle);
///back button
setContentView(R.layout.activity_search_result_list);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.container, fragobj).commit();
}
}
#Override
public void onItemClick(AdapterView<?> arg0, View textView, int rowNumber, long arg3) {
Intent intent = new Intent(this, PropertyDetailActivity.class);
PropertyObject po = (PropertyObject) arg0.getAdapter().getItem((int)arg3);
intent.putExtra("listingID",po.getID());
startActivity(intent);
}
EDIT:
All right. I changed my API level from 8 to 11 to.
Also I added getActionBar().setDisplayHomeAsUpEnabled(true); to onCreate() of activity.
And changes the onOptionsItemSelected as follows.
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
Intent intent=new Intent(PropertyDetailActivity.this, AboutActivity.class);
startActivity(intent);
return true;
case R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
case R.id.up:
NavUtils.navigateUpFromSameTask(this);
return true;
case R.id.homeAsUp:
NavUtils.navigateUpFromSameTask(this);
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
BUT none of the switch cases gets the chance to run when I click the back button in the action bar!
This might be a bit of a lengthy post so my apologies in advance.
I'm using the master/detail flow to display a list of items and when clicking on it it opens the detail view. The items are loaded from a webservice.
It works great on the tablet with the fragments but on the phone it keeps crashing. It can display the item detail (CheatViewPageIndicator.java) properly but when I use the "up" button on the top left in the action bar to return to the parent activity (CheatListActivity.java) the app keeps crashing with a nullpointer exception. I think I'm loading the data from the webservice at the wrong location and that's why it crashes. I'm going to write my code here and hopefully someone can give me an advice how I would have to do this the correct way.
(I've trimmed the classes a bit to shorten the post a bit.)
The "master" activity:
public class CheatListActivity extends FragmentActivity implements CheatListFragment.Callbacks, ReportCheatDialogListener, RateCheatDialogListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheat_list);
settings = getSharedPreferences(Konstanten.PREFERENCES_FILE, 0);
editor = settings.edit();
cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
cheatProgressDialog = ProgressDialog.show(this, getString(R.string.please_wait) + "...", getString(R.string.retrieving_data) + "...", true);
handleIntent(getIntent());
if (findViewById(R.id.cheat_detail_container) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
// In two-pane mode, list items should be given the
// 'activated' state when touched.
((CheatListFragment) getSupportFragmentManager().findFragmentById(R.id.cheat_list)).setActivateOnItemClick(true);
}
cheatProgressDialog.dismiss();
// TODO: If exposing deep links into your app, handle intents here.
}
private void handleIntent(final Intent intent) {
new Thread(new Runnable() {
#Override
public void run() {
gameObj = new Gson().fromJson(intent.getStringExtra("gameObj"), Game.class);
runOnUiThread(new Runnable() {
#Override
public void run() {
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setTitle(gameObj.getGameName());
getActionBar().setSubtitle(gameObj.getSystemName());
}
});
try {
if (cm.getActiveNetworkInfo() != null) {
if (member == null) {
cheats = Webservice.getCheatList(gameObj, 0);
} else {
cheats = Webservice.getCheatList(gameObj, member.getMid());
}
cheatsArrayList = new ArrayList<Cheat>();
if (cheats != null) {
for (int j = 0; j < cheats.length; j++) {
cheatsArrayList.add(cheats[j]);
}
} else {
Log.e("CheatListActivity()", "Webservice.getCheatList() == null");
}
for (int i = 0; i < cheats.length; i++) {
Log.d("cheats", cheats[i].getCheatTitle());
}
gameObj.setCheats(cheats);
// Put game object to local storage for large games like
// Pokemon
editor.putString(Konstanten.PREFERENCES_TEMP_GAME_OBJECT_VIEW, new Gson().toJson(gameObj));
editor.commit();
} else {
Log.e("CheatTitleList:getCheats()", "No Network");
Toast.makeText(CheatListActivity.this, R.string.no_internet, Toast.LENGTH_SHORT).show();
}
} catch (Exception ex) {
Log.e(getClass().getName(), "Error executing getCheats()", ex);
}
}
}).start();
}
public Cheat[] getCheatsForFragment(final Intent intent) {
gameObj = new Gson().fromJson(intent.getStringExtra("gameObj"), Game.class);
runOnUiThread(new Runnable() {
#Override
public void run() {
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setTitle(gameObj.getGameName());
getActionBar().setSubtitle(gameObj.getSystemName());
}
});
try {
if (cm.getActiveNetworkInfo() != null) {
if (member == null) {
cheats = Webservice.getCheatList(gameObj, 0);
} else {
cheats = Webservice.getCheatList(gameObj, member.getMid());
}
cheatsArrayList = new ArrayList<Cheat>();
if (cheats != null) {
for (int j = 0; j < cheats.length; j++) {
cheatsArrayList.add(cheats[j]);
}
} else {
Log.e("CheatListActivity()", "Webservice.getCheatList() == null");
}
for (int i = 0; i < cheats.length; i++) {
Log.d("cheats", cheats[i].getCheatTitle());
}
gameObj.setCheats(cheats);
// Put game object to local storage for large games like Pokemon
editor.putString(Konstanten.PREFERENCES_TEMP_GAME_OBJECT_VIEW, new Gson().toJson(gameObj));
editor.commit();
} else {
Log.e("CheatTitleList:getCheats()", "No Network");
Toast.makeText(this, R.string.no_internet, Toast.LENGTH_SHORT).show();
}
} catch (Exception ex) {
Log.e(getClass().getName(), "Error executing getCheats()", ex);
}
return cheats;
}
/**
* Callback method from {#link CheatListFragment.Callbacks} indicating that
* the item with the given ID was selected.
*/
#Override
public void onItemSelected(int id) {
if (mTwoPane) {
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
visibleCheat = cheats[id];
cheatForumFragment = new CheatForumFragment();
cheatDetailMetaFragment = new CheatDetailMetaFragment();
// VIEW FOR TABLETS
Bundle arguments = new Bundle();
arguments.putInt(CheatDetailTabletFragment.ARG_ITEM_ID, id);
arguments.putString("cheatObj", new Gson().toJson(cheats[id]));
arguments.putString("cheatForumFragment", new Gson().toJson(cheatForumFragment));
arguments.putString("cheatDetailMetaFragment", new Gson().toJson(cheatDetailMetaFragment));
cheatDetailFragment = new CheatDetailTabletFragment();
cheatDetailFragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction().replace(R.id.cheat_detail_container, cheatDetailFragment).commit();
} else {
// In single-pane mode, simply start the detail activity
// for the selected item ID.
// Intent detailIntent = new Intent(this, YyyDetailActivity.class);
// detailIntent.putExtra(YyyDetailFragment.ARG_ITEM_ID, id);
// startActivity(detailIntent);
editor.putInt(Konstanten.PREFERENCES_PAGE_SELECTED, id);
editor.commit();
// Using local Preferences to pass data for large game objects
// (instead of intent) such as Pokemon
Intent explicitIntent = new Intent(CheatListActivity.this, CheatViewPageIndicator.class);
explicitIntent.putExtra("selectedPage", id);
explicitIntent.putExtra("layoutResourceId", R.layout.activity_cheatview_pager);
explicitIntent.putExtra("pageIndicatorColor", Konstanten.CYAN_DARK);
startActivity(explicitIntent);
}
}
}
And the fragment for the listview.
public class CheatListFragment extends ListFragment {
/**
* The serialization (saved instance state) Bundle key representing the
* activated item position. Only used on tablets.
*/
private static final String STATE_ACTIVATED_POSITION = "activated_position";
/**
* The fragment's current callback object, which is notified of list item
* clicks.
*/
private Callbacks mCallbacks = sDummyCallbacks;
/**
* The current activated item position. Only used on tablets.
*/
private int mActivatedPosition = ListView.INVALID_POSITION;
/**
* A callback interface that all activities containing this fragment must
* implement. This mechanism allows activities to be notified of item
* selections.
*/
public interface Callbacks {
/**
* Callback for when an item has been selected.
*/
public void onItemSelected(int position);
}
/**
* A dummy implementation of the {#link Callbacks} interface that does
* nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
#Override
public void onItemSelected(int id) {
}
};
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public CheatListFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
cheatListActivity = (CheatListActivity) getActivity();
fontRoboto = Tools.getFontRobotoRegular(getActivity().getAssets());
settings = cheatListActivity.getSharedPreferences(Konstanten.PREFERENCES_FILE, 0);
gameObj = new Gson().fromJson(settings.getString(Konstanten.PREFERENCES_TEMP_GAME_OBJECT_VIEW, null), Game.class);
if( gameObj == null) {
new GetCheatsTask().execute(new Game());
} else {
new GetCheatsTask().execute(gameObj);
}
}
private class GetCheatsTask extends AsyncTask<Game, Void, Void> {
#Override
protected Void doInBackground(Game... params) {
if (params[0].getCheats() == null) {
cheats = cheatListActivity.getCheatsForFragment(cheatListActivity.getIntent());
} else {
cheats = params[0].getCheats();
}
for (int i = 0; i < cheats.length; i++) {
Log.d("Cheat Item ", cheats[i].getCheatTitle());
cheatsArrayList.add(cheats[i]);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
cheatAdapter = new CheatAdapter(getActivity(), R.layout.cheatlist_item, cheatsArrayList);
setListAdapter(cheatAdapter);
}
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Restore the previously serialized activated item position.
if (savedInstanceState != null && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Activities containing this fragment must implement its callbacks.
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
#Override
public void onDetach() {
super.onDetach();
// Reset the active callbacks interface to the dummy implementation.
mCallbacks = sDummyCallbacks;
}
#Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
// mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
mCallbacks.onItemSelected(position);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mActivatedPosition != ListView.INVALID_POSITION) {
// Serialize and persist the activated item position.
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
}
}
/**
* Turns on activate-on-click mode. When this mode is on, list items will be
* given the 'activated' state when touched.
*/
public void setActivateOnItemClick(boolean activateOnItemClick) {
// When setting CHOICE_MODE_SINGLE, ListView will automatically
// give items the 'activated' state when touched.
getListView().setChoiceMode(activateOnItemClick ? ListView.CHOICE_MODE_SINGLE : ListView.CHOICE_MODE_NONE);
}
private void setActivatedPosition(int position) {
if (position == ListView.INVALID_POSITION) {
getListView().setItemChecked(mActivatedPosition, false);
} else {
getListView().setItemChecked(position, true);
}
mActivatedPosition = position;
}
private class CheatAdapter extends ArrayAdapter<Cheat> {
private final ArrayList<Cheat> items;
public CheatAdapter(Context context, int textViewResourceId, ArrayList<Cheat> items) {
super(context, textViewResourceId, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.cheatlist_item, null);
}
try {
Cheat cheat = items.get(position);
if (cheat != null) {
TextView tt = (TextView) v.findViewById(R.id.game_title);
tt.setText(cheat.getCheatTitle());
tt.setTypeface(fontRoboto);
// Durchschnittsrating (nicht Member-Rating)
RatingBar ratingBar = (RatingBar) v.findViewById(R.id.small_ratingbar);
ratingBar.setNumStars(5);
ratingBar.setRating(cheat.getRatingAverage() / 2);
ImageView flag_newaddition = (ImageView) v.findViewById(R.id.newaddition);
if (cheat.getDayAge() < Konstanten.CHEAT_DAY_AGE_SHOW_NEWADDITION_ICON) {
flag_newaddition.setImageResource(R.drawable.flag_new);
flag_newaddition.setVisibility(View.VISIBLE);
} else {
flag_newaddition.setVisibility(View.GONE);
}
ImageView flag_screenshots = (ImageView) v.findViewById(R.id.screenshots);
if (cheat.isScreenshots()) {
flag_screenshots.setVisibility(View.VISIBLE);
flag_screenshots.setImageResource(R.drawable.flag_img);
} else {
flag_screenshots.setVisibility(View.GONE);
}
ImageView flag_german = (ImageView) v.findViewById(R.id.flag);
if (cheat.getLanguageId() == 2) { // 2 = Deutsch
flag_german.setVisibility(View.VISIBLE);
flag_german.setImageResource(R.drawable.flag_german);
} else {
flag_german.setVisibility(View.GONE);
}
}
} catch (Exception e) {
Log.e(getClass().getName() + ".getView ERROR:", e.getMessage());
}
return v;
}
}
}
Detail view in two-pane mode (on a tablet):
public class CheatDetailTabletFragment extends Fragment implements OnClickListener {
/**
* The fragment argument representing the item ID that this fragment
* represents.
*/
public static final String ARG_ITEM_ID = "item_id";
/**
* The dummy content this fragment is presenting.
*/
private CheatContent.CheatItem mItem;
private View rootView;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public CheatDetailTabletFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ca = (CheatListActivity) getActivity();
cheatTitleTypeface = Tools.getFontRobotoThin(getActivity().getAssets());
cheatTextTypeface = Tools.getFontRobotoRegular(getActivity().getAssets());
settings = getActivity().getSharedPreferences(Konstanten.PREFERENCES_FILE, 0);
editor = settings.edit();
if (getArguments().containsKey(ARG_ITEM_ID)) {
// Load the dummy content specified by the fragment
// arguments. In a real-world scenario, use a Loader
// to load content from a content provider.
mItem = CheatContent.ITEM_MAP.get(getArguments().getInt(ARG_ITEM_ID));
cheatObj = new Gson().fromJson(getArguments().getString("cheatObj"), Cheat.class);
cheatForumFragment = new Gson().fromJson(getArguments().getString("cheatForumFragment"), CheatForumFragment.class);
cheatDetailMetaFragment = new Gson().fromJson(getArguments().getString("cheatDetailMetaFragment"), CheatDetailMetaFragment.class);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_cheat_detail, container, false);
// ...
// Show the dummy content as text in a TextView.
if (mItem != null) {
((TextView) rootView.findViewById(R.id.text_cheat_before_table)).setText(mItem.getCheatTitle());
((TextView) rootView.findViewById(R.id.text_cheat_title)).setText(mItem.getCheatId());
}
// ...
populateView();
return rootView;
}
/**
* Create Layout
*/
private void populateView() {
// fills the view. no problems here.
}
/**
* Populate Table Layout
*/
private void fillTableContent() {
// filling table content here. no problems here.
}
private void fillSimpleContent() {
// filling with other content. works fine, too.
}
}
Detail view in one-pane mode (on a phone):
public class CheatViewPageIndicator extends FragmentActivity implements ReportCheatDialogListener, RateCheatDialogListener {
// define variables...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = LayoutInflater.from(this);
intent = getIntent();
viewLayout = inflater.inflate(intent.getIntExtra("layoutResourceId", R.layout.activity_cheatview_pager), null);
setContentView(viewLayout);
settings = getSharedPreferences(Konstanten.PREFERENCES_FILE, 0);
editor = settings.edit();
getActionBar().setHomeButtonEnabled(true);
getActionBar().setDisplayHomeAsUpEnabled(true);
try {
gameObj = new Gson().fromJson(settings.getString(Konstanten.PREFERENCES_TEMP_GAME_OBJECT_VIEW, null), Game.class);
if (gameObj == null) {
gameObj = new Gson().fromJson(intent.getStringExtra("gameObj"), Game.class);
}
editor.putString(Konstanten.PREFERENCES_TEMP_GAME_OBJECT_VIEW, new Gson().toJson(gameObj));
editor.commit();
pageSelected = intent.getIntExtra("selectedPage", 0);
activePage = pageSelected;
pageIndicatorColor = intent.getIntExtra("pageIndicatorColor", Konstanten.CYAN_DARK);
cheatObj = gameObj.getCheats();
visibleCheat = cheatObj[pageSelected];
getActionBar().setTitle(gameObj.getGameName());
getActionBar().setSubtitle(gameObj.getSystemName());
initialisePaging();
} catch (Exception e) {
Log.e(CheatViewPageIndicator.class.getName(), e.getMessage() + "");
}
}
private void initialisePaging() {
// ...
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.handset_cheatview_menu, menu);
// Search
getMenuInflater().inflate(R.menu.search_menu, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return super.onCreateOptionsMenu(menu);
}
#Override
protected void onResume() {
super.onResume();
invalidateOptionsMenu();
}
public ConnectivityManager getConnectivityManager() {
if (cm == null) {
cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
}
return cm;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
// onBackPressed();
// return true;
Intent upIntent = new Intent(this, CheatListActivity.class);
NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
// This activity is NOT part of this app's task, so create a new
// task when navigating up, with a synthesized back stack.
TaskStackBuilder.create(this)
// Add all of this activity's parents to the back stack
.addNextIntentWithParentStack(upIntent)
// Navigate up to the closest parent
.startActivities();
} else {
// This activity is part of this app's task, so simply
// navigate up to the logical parent activity.
// NavUtils.navigateUpTo(this, upIntent);
upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(upIntent);
finish();
}
return true;
}
return super.onOptionsItemSelected(item);
}
}
So in one pane mode (on a phone) when I click the "up" button in the action bar from CheatViewPageIndicator.java to get one up to CheatListActivity.java I get a nullpointer exception pointing to this line:
gameObj = new Gson().fromJson(intent.getStringExtra("gameObj"), Game.class);
Seems like the "intent" is null when going back. I'm wondering why that is? What do I need to do to keep the data in the intent? (or any other solution how to get rid of the nullpointer is perfectly fine with me, too). I'm a bit desperate, I've been searching for a solution for too long.
Thanks a lot for the help.
I generally use another way of specifying parent acivities, and it includes an attribute in the manifest file.
In the activity tag of CheatViewPageIndicator.java, add this attribute:
<activity
...
android:parentActivityName="your.app.package.CheatListActivity" >
</activity>
and comment out all the lines you wrote for upIntent.This should do the trick.
I'm almost sure the problem comes from onOptionsItemSelected() in CheatViewPageIndicator. You don't need to start a new activity there, in master-detail pattern there's always one and the same activity at a time. Only fragments are changing.
To provide an ability to properly use "up" button you should just call fragmentTransaction.addToBackStack(null) while adding fragments. Android will handle all stack logic by itself. Don't do anything at all in android.R.id.home case, you don't need it.
I ran into this problem and solved it by putting the intent extras into the upIntent right before Nav so that they would get passed up to the parent List activity.
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
...
Intent upIntent = new Intent(this, CheatListActivity.class);
--> upIntent.putExtras(getIntent().getExtras());
NavUtils.getParentActivityIntent(this);