I am new to Android Programming and Android studio.
Basically, I am creating a Memo App by Android Studio, created a Tabbed Activity(Action Bar Tabs(with viewpager)), then created 4 Fragment class and layout, all codes generated automatically by Android Studio.
But I get stuck in Tab changing......
package com.example.user.memoapp;
import java.util.Locale;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.FragmentPagerAdapter;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
public class MainActivity extends ActionBarActivity implements ActionBar.TabListener {
/**
* 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;
/**
* The {#link ViewPager} that will host the section contents.
*/
static ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the four
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
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) {
}
/**
* 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)
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
// Show 4 total pages.
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
case 3:
return getString(R.string.title_section4).toUpperCase(l);
}
return null;
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public int mPage;
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_all, container, false);
return rootView;
}
}
}
I tried to change getItem() to something Like this:
#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)
//return PlaceholderFragment.newInstance(position + 1);
switch(position){
case 0:
return new All();
case 1:
return new Urgent();
case 2:
return new Late();
case 3:
return new Done();
default:
return null;
}
}
But it dont even work, said "Unfortunately, MemoApp has stopped".
Here are the codes of the 4 fragment class, they are all generated by Android Studio, are basically the same....
All.java:
package com.example.user.memoapp;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link All.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link All#newInstance} factory method to
* create an instance of this fragment.
*/
public class All 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;
/**
* 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 all.
*/
// TODO: Rename and change types and number of parameters
public static All newInstance(String param1, String param2) {
All fragment = new All();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public All() {
// Required empty public constructor
}
#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
return inflater.inflate(R.layout.fragment_all, 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(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#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
public void onFragmentInteraction(Uri uri);
}
}
Urgent.java
package com.example.user.memoapp;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link Urgent.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link Urgent#newInstance} factory method to
* create an instance of this fragment.
*/
public class Urgent 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;
/**
* 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 Urgent.
*/
// TODO: Rename and change types and number of parameters
public static Urgent newInstance(String param1, String param2) {
Urgent fragment = new Urgent();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public Urgent() {
// Required empty public constructor
}
#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
return inflater.inflate(R.layout.fragment_urgent, 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(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#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
public void onFragmentInteraction(Uri uri);
}
}
Late.java,
package com.example.user.memoapp;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link Late.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link Late#newInstance} factory method to
* create an instance of this fragment.
*/
public class Late 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;
/**
* 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 Late.
*/
// TODO: Rename and change types and number of parameters
public static Late newInstance(String param1, String param2) {
Late fragment = new Late();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public Late() {
// Required empty public constructor
}
#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
return inflater.inflate(R.layout.fragment_late, 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(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#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
public void onFragmentInteraction(Uri uri);
}
}
Done.java:
package com.example.user.memoapp;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link Done.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link Done#newInstance} factory method to
* create an instance of this fragment.
*/
public class Done 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;
/**
* 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 Done.
*/
// TODO: Rename and change types and number of parameters
public static Done newInstance(String param1, String param2) {
Done fragment = new Done();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public Done() {
// Required empty public constructor
}
#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
return inflater.inflate(R.layout.fragment_done, 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(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#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
public void onFragmentInteraction(Uri uri);
}
}
Sorry for extremely long boring coding...
As the logcat says, you are assigning your MainActivity to All.mListener, which is an OnFragmentInteractionListener, but MainActivity does not implement this interface
So you need to make MainActivity implement OnFragmentInteractionListener:
public class MainActivity extends ActionBarActivity implements
ActionBar.TabListener, OnFragmentInteractionListener {
// ... all your Activity code ...
#Override
public void onFragmentInteraction(Uri uri) {
// ... implement communication here ...
}
}
This will prevent the app from crashing, but still you will need to implement communication between Fragments and Activity. Change the parameters required by onFragmentInteraction() if you need to send something else, or remove the interface and any reference of mListener if you don't need that kind of communication.
Good luck!
Related
I have been trying to Design an App That has PANEL like Google Drawers.
• MainActivity
package skynet.com.testnavigationpanel;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends ActionBarActivity
implements NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
private Toolbar mToolbar;
Intent i=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
setSupportActionBar(mToolbar);
mNavigationDrawerFragment = (NavigationDrawerFragment)getFragmentManager().findFragmentById(R.id.fragment_drawer);
// Set up the drawer.
mNavigationDrawerFragment.setup(R.id.fragment_drawer, (DrawerLayout) findViewById(R.id.drawer), mToolbar);
// populate the navigation drawer
mNavigationDrawerFragment.setUserData("Falcon Shield", "We Protect Your Device!", BitmapFactory.decodeResource(getResources(), R.drawable.shieldavatar));
}
public void login_signup(View v)
{
switch(v.getId())
{
case R.id.log_in:
i=new Intent(this,Login.class);
startActivityForResult(i, 500);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
break;
case R.id.sign_up:
i=new Intent(this,Signup.class);
startActivityForResult(i, 500);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}
#Override
public void onNavigationDrawerItemSelected(int position)
{
// update the main content by replacing fragments
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
return super.onCreateOptionsMenu(menu);
}
#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);
}
public void onSectionAttached(int anInt) {
}
}
•NavigationDrawerFragment
package skynet.com.testnavigationpanel;
import android.app.Activity;
import android.app.Fragment;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Fragment used for managing interactions for and presentation of a navigation drawer.
* See the <a href="https://developer.android.com/design/patterns/navigation-drawer.html#Interaction">
* design guidelines</a> for a complete explanation of the behaviors implemented here.
*/
public class NavigationDrawerFragment extends Fragment implements NavigationDrawerCallbacks {
/**
* Remember the position of the selected item.
*/
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
/**
* Per the design guidelines, you should show the drawer on launch until the user manually
* expands it. This shared preference tracks this.
*/
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
/**
* A pointer to the current callbacks instance (the Activity).
*/
private NavigationDrawerCallbacks mCallbacks;
/**
* Helper component that ties the action bar to the navigation drawer.
*/
private ActionBarDrawerToggle mActionBarDrawerToggle;
private DrawerLayout mDrawerLayout;
private RecyclerView mDrawerList;
private View mFragmentContainerView;
private int mCurrentSelectedPosition = 0;
private boolean mFromSavedInstanceState;
private boolean mUserLearnedDrawer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Read in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
mDrawerList = (RecyclerView) view.findViewById(R.id.drawerList);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mDrawerList.setLayoutManager(layoutManager);
mDrawerList.setHasFixedSize(true);
final List<NavigationItem> navigationItems = getMenu();
NavigationDrawerAdapter adapter = new NavigationDrawerAdapter(navigationItems);
adapter.setNavigationDrawerCallbacks(this);
mDrawerList.setAdapter(adapter);
selectItem(mCurrentSelectedPosition);
return view;
}
public boolean isDrawerOpen() {
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
}
public ActionBarDrawerToggle getActionBarDrawerToggle() {
return mActionBarDrawerToggle;
}
public DrawerLayout getDrawerLayout() {
return mDrawerLayout;
}
#Override
public void onNavigationDrawerItemSelected(int position) {
selectItem(position);
}
public List getMenu() {
List items= new ArrayList<>();
items.add(new NavigationItem(getString(R.string.homeFrag),getResources().getDrawable(R.drawable.ic_home)));
items.add(new NavigationItem(getString(R.string.loginFrag),getResources().getDrawable(R.drawable.ic_login)));
items.add(new NavigationItem(getString(R.string.signupFrag),getResources().getDrawable(R.drawable.ic_signup)));
items.add(new NavigationItem(getString(R.string.settingFrag),getResources().getDrawable(R.drawable.ic_setting )));
items.add(new NavigationItem(getString(R.string.shareFrag),getResources().getDrawable(R.drawable.ic_share )));
items.add(new NavigationItem(getString(R.string.aboutFrag),getResources().getDrawable(R.drawable.ic_about )));
return items;
}
public void showBackButton(){
if(getActivity()instanceof ActionBarActivity){
((ActionBarActivity)getActivity()).getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* #param fragmentId The android:id of this fragment in its activity's layout.
* #param drawerLayout The DrawerLayout containing this fragment's UI.
* #param toolbar The Toolbar of the activity.
*/
public void setup(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) {
mFragmentContainerView = (View) getActivity().findViewById(fragmentId).getParent();
mDrawerLayout = drawerLayout;
mDrawerLayout.setStatusBarBackgroundColor(getResources().getColor(R.color.myPrimaryDarkColor));
mActionBarDrawerToggle = new ActionBarDrawerToggle(getActivity(), mDrawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
if (!isAdded()) return;
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (!isAdded()) return;
if (!mUserLearnedDrawer) {
mUserLearnedDrawer = true;
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(getActivity());
sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
}
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
// per the navigation drawer design guidelines.
if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mActionBarDrawerToggle.syncState();
}
});
mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);
}
private void selectItem(int position) {
mCurrentSelectedPosition = position;
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
if (mCallbacks != null) {
mCallbacks.onNavigationDrawerItemSelected(position);
}
((NavigationDrawerAdapter) mDrawerList.getAdapter()).selectPosition(position);
}
public void openDrawer() {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
public void closeDrawer() {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (NavigationDrawerCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
}
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Forward the new configuration the drawer toggle component.
mActionBarDrawerToggle.onConfigurationChanged(newConfig);
}
public void setUserData(String user, String email, Bitmap avatar) {
ImageView avatarContainer = (ImageView) mFragmentContainerView.findViewById(R.id.imgAvatar);
((TextView) mFragmentContainerView.findViewById(R.id.txtUserEmail)).setText(email);
((TextView) mFragmentContainerView.findViewById(R.id.txtUsername)).setText(user);
avatarContainer.setImageDrawable(new RoundImage(avatar));
}
public View getGoogleDrawer() {
return mFragmentContainerView.findViewById(R.id.googleDrawer);
}
public static class RoundImage extends Drawable {
private final Bitmap mBitmap;
private final Paint mPaint;
private final RectF mRectF;
private final int mBitmapWidth;
private final int mBitmapHeight;
public RoundImage(Bitmap bitmap) {
mBitmap = bitmap;
mRectF = new RectF();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
mBitmapWidth = mBitmap.getWidth();
mBitmapHeight = mBitmap.getHeight();
}
#Override
public void draw(Canvas canvas) {
canvas.drawOval(mRectF, mPaint);
}
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRectF.set(bounds);
}
#Override
public void setAlpha(int alpha) {
if (mPaint.getAlpha() != alpha) {
mPaint.setAlpha(alpha);
invalidateSelf();
}
}
#Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public int getIntrinsicWidth() {
return mBitmapWidth;
}
#Override
public int getIntrinsicHeight() {
return mBitmapHeight;
}
public void setAntiAlias(boolean aa) {
mPaint.setAntiAlias(aa);
invalidateSelf();
}
#Override
public void setFilterBitmap(boolean filter) {
mPaint.setFilterBitmap(filter);
invalidateSelf();
}
#Override
public void setDither(boolean dither) {
mPaint.setDither(dither);
invalidateSelf();
}
public Bitmap getBitmap() {
return mBitmap;
}
}
}
Kindly Guide me in Mentioning the Right code into Below Method of MainActivity.
onNavigationDrawerItemSelect(int position)
{
//codes for fragments That i dont Know how to write
}
My Fragment Class(Please Check the Code if its Right or needs to be changed)
package skynet.com.testnavigationpanel;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Evan on 28-Dec-15.
*/
public class HomeFragment extends Fragment {
public static HomeFragment newInstance(){
HomeFragment fragment=new HomeFragment();
return fragment;
}
public HomeFragment()
{
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.activity_main,container,false);
return rootView;
}
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
((MainActivity)activity).onSectionAttached(1);
}
}
Same Goes with my Other fragments for login, signup, about, share, etc..with Relevant Changes in Layout id and Names.
Devs, Kindly Help ! Thanks
I want to track focused node to perform some action after user inactivity on that node. But focused for my application means that there could be only 1 focus node in the entire application (application has numerous Stages and they creation are out of my control. I also cannot force different department of my company to use registry to register stages after they create them).
E.g. I have a property for focused component scene.focusOwnerProperty(), I can track whether Stage is stage.focusedProperty() but I'm searching the way to retrieve all stages.
Do you know the way?
I found a solution. com.sun.javafx.stage.StageHelper.getStages() list all stages.
You can Use Window[] windows = Window.getWindows(); this is part of the Public Api and works fine for me.
Thanks guys for answers. I write a class which provides an easy way to track currently focused Node and "focused" Scene. "Focused" means the focused component from focused Stage. If there are any mistakes in my code I would be grateful for if you notice and inform me.
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.stage.Stage;
import com.sun.javafx.stage.StageHelper;
/**
* Tracks focused component among all {#link Stage}'s. Currently this is singleton but it will make service
* out of it.
*
* #author created: kszymanek on 8 sty 2016 15:19:32
*/
public class GlobalFocusTracker
{
private static final GlobalFocusTracker INSTANCE = new GlobalFocusTracker();
/**
* tracks stage list and each stage and registers {#link #sceneListener} on
* the focused stage
*/
private StagesListener stagesListener;
/**
* tracks scene of the focused stage and registers
* {#link #focusOwnerListener} on it
*/
private SceneListener sceneListener;
private FocusOwnerListener focusOwnerListener;
private ReadOnlyObjectWrapper focusedNodeProperty = new ReadOnlyObjectWrapper();
private ReadOnlyObjectWrapper focusedSceneProperty = new ReadOnlyObjectWrapper();
private GlobalFocusTracker()
{
}
public static GlobalFocusTracker getInstance()
{
return INSTANCE;
}
/**
* #return current {#link Scene} from the currently focused {#link Stage}
*/
public ReadOnlyObjectProperty focusedSceneProperty()
{
init();
return focusedSceneProperty.getReadOnlyProperty();
}
/**
* #return focused node among all stages. There could be one focus owner at
* the time. If end user focuses some other application there would
* be no focus node.
*/
public ReadOnlyObjectProperty focusedNodeProperty()
{
init();
return focusedNodeProperty.getReadOnlyProperty();
}
private void init()
{
if(stagesListener == null)
{
stagesListener = new StagesListener();
sceneListener = new SceneListener();
focusOwnerListener = new FocusOwnerListener();
stagesListener.register();
}
}
private class StagesListener implements ListChangeListener, ChangeListener
{
private ObservableList stages;
#Override
public void onChanged(javafx.collections.ListChangeListener.Change aChange)
{
while(aChange.next())
{
if(aChange.wasRemoved())
{
for(Stage stage : aChange.getRemoved())
{
stage.focusedProperty().removeListener(this);
}
}
if(aChange.wasAdded())
{
for(Stage stage : aChange.getAddedSubList())
{
stage.focusedProperty().addListener(this);
}
}
}
}
#Override
public void changed(ObservableValue aObservable, Boolean aOld, Boolean aNew)
{
Stage focusedStage = null;
for(Stage stage : stages)
{
if(stage.isFocused())
{
focusedStage = stage;
}
}
sceneListener.register(focusedStage);
}
public void register()
{
if(stages == null)
{
stages = StageHelper.getStages();
stages.addListener(this);
for(Stage stage : stages)
{
stage.focusedProperty().addListener(this);
if(stage.isFocused())
{
sceneListener.register(stage);
}
}
}
}
}
private class SceneListener implements ChangeListener
{
private Stage stage;
#Override
public void changed(ObservableValue aObservable, Scene aOld, Scene aNew)
{
focusOwnerListener.register(aNew);
}
/**
* #param aStage is {#code null} protected
*/
public void register(Stage aStage)
{
if(aStage != stage)
{
unregister();
stage = aStage;
if(aStage != null)
{
aStage.sceneProperty().addListener(this);
focusOwnerListener.register(aStage.getScene());
}
}
}
public void unregister()
{
if(stage != null)
{
focusOwnerListener.unregister();
stage.sceneProperty().removeListener(this);
stage = null;
}
}
}
private class FocusOwnerListener implements ChangeListener
{
private Scene scene;
#Override
public void changed(ObservableValue aObservable, Node aOld, Node aNew)
{
focusedNodeProperty.set(aNew);
}
/**
* #param aScene can be {#code null} in such case it is only an equivalent
* of {#link #unregister()}
*/
public void register(Scene aScene)
{
if(scene != aScene)
{
unregister();
scene = aScene;
focusedSceneProperty.set(aScene);
if(aScene != null)
{
focusedNodeProperty.set(aScene.getFocusOwner());
aScene.focusOwnerProperty().addListener(this);
}
}
}
public void unregister()
{
if(scene != null)
{
focusedSceneProperty.set(null);
focusedNodeProperty.set(null);
scene.focusOwnerProperty().removeListener(this);
scene = null;
}
}
}
}
I'm following a tutorial and trying to build in a grid view into my fragment and every time I launch the app it crashes. I opened up LogCat and it gives me nothing... Can someone help me find out what I can do to get this to display correctly and not crash the app? Thank you!!!
Below I've included my Main Activity, GridView Adapter and Fragment...
MainActivity
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
public class MainActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private Char
Sequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
// Set the first title
mTitle = "Inventory";
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
// Remove shadow under actionbar
getSupportActionBar().setElevation(0);
}
#Override
public void onNavigationDrawerItemSelected(int position) {
Fragment objFragment = null;
switch (position) {
case 0:
objFragment = new Inventory_Fragment();
mTitle = getString(R.string.title_section1);
break;
case 1:
objFragment = new Orders_Fragment();
mTitle = getString(R.string.title_section2);
break;
case 2:
objFragment = new Cart_Fragment();
mTitle = getString(R.string.title_section3);
break;
case 3:
objFragment = new Settings_Fragment();
mTitle = getString(R.string.title_section4);
break;
}
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, objFragment)
.commit();
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
case 4:
mTitle = getString(R.string.title_section4);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#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);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.inventory_layout, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
// MARK: - Helpers
public void setActionBarTitle(String title) {
getSupportActionBar().setTitle(title);
}
}
GridViewAdapter
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
/**
* Created by kenbarlow on 5/20/15.
*/
public class GridViewAdapter extends BaseAdapter {
private Context context;
public GridViewAdapter(Context context) {
context = context;
}
private int[] icons = {
// Temporary
R.drawable.image1,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4,
R.drawable.image5,
R.drawable.image6,
R.drawable.image7,
R.drawable.image8,
R.drawable.image9,
R.drawable.image10,
R.drawable.image11,
R.drawable.image12,
R.drawable.image13,
R.drawable.image14,
R.drawable.image15,
R.drawable.image16,
R.drawable.image17
};
#Override
public int getCount() {
return icons.length;
}
#Override
public Object getItem(int position){
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
imageView.setLayoutParams(new GridView.LayoutParams(100, 100));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(10, 10, 10, 10);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(icons[position]);
return imageView;
}
}
Inventory_Fragment --- I Feel like the problem is in here but I'm not sure.
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
/**
* Created by kenbarlow on 5/19/15.
*/
public class Inventory_Fragment extends Fragment {
View rootView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.inventory_layout, container, false);
GridView gridview = (GridView) getActivity().findViewById(R.id.gridview);
gridview.setAdapter(new GridViewAdapter(this));
return rootView;
}
}
I guess your are trying to find a gridview in the activity's layout, which is wrong because the gridview is in the Fragment's layout.
Please change in your fragment code:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.inventory_layout, container, false);
GridView gridview = (GridView) rootView.findViewById(R.id.gridview);
if(gridview != null){
gridview.setAdapter(new GridViewAdapter(getActivity()));
}
return rootView;
}
If it's not the cause of the problem, please post a stacktrace when the crash happen (it should have already been done).
I have not looked at all the code yet. I reviewed GridViewAdapter and Inventory_Fragment.
Remove getItemId method in GridViewAdapter. You don't use it anyway. It is possible that the BaseAdapter is referencing it, and returning it null from that method may crash the adapter.
Code suggestion, return an item for this method:
#Override
public Object getItem(int position){
return icons[position];
}
LogCat and it gives me nothing...
if literally nothing, try to reset LogCat.
as i see in these lines
rootView = inflater.inflate(R.layout.inventory_layout, container, false);
GridView gridview = (GridView) getActivity().findViewById(R.id.gridview);
you are inflating and makeing rootView to find your inner layouts. so instead of getActivity() in second line use your rootView.
and remember to put your gridView layout inside inventory_layout
I am not sure if it is the only issue or not, but this one looks a bit wrong.
In your Inventory_Fragment class:
gridview.setAdapter(new GridViewAdapter(this));
You should change it to this:
gridview.setAdapter(new GridViewAdapter(getActivity()));
Also please upload your layouts and/or logcat report here. It is hard to go through the code like this.
How i can refresh listfragment? no tutorials from net work :(
i have no idea, how reload this listfragment. I tried reload by transaktionmanager, but its colide with ActionBar.TabListener, this is not support.v4. how can i retrieve new data from loadermanager and update listfragment?
Activity:
package sk.test;
import android.app.ActionBar;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.app.FragmentTransaction;
import android.support.v4.app.LoaderManager;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import java.util.List;
import java.util.Locale;
import sk.test.frags.TodoFragment;
import sk.test.prefs.EditPreferences;
import sk.test.task.DataListLoader;
import sk.test.xml.Item;
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
private TodoFragment todoFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.action_settings:
startActivity(new Intent(getApplicationContext(), EditPreferences.class));
return true;
case R.id.refresh:
//HERE CODE FOR RELOAD todoFragment.reloadData() ????
return true;
default:
return true;
}
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private boolean wantDone = false;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
todoFragment = new TodoFragment();
this.wantDone = position == 0 ? false : true;
Bundle args = new Bundle();
args.putBoolean(TodoFragment.TASK_TYPE, this.wantDone);
todoFragment.setArguments(args);
return todoFragment;
}
#Override
public int getCount() {
return 2;
}
public boolean getWantDone(){
return this.wantDone;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.todotask_planned).toUpperCase(l);
case 1:
return getString(R.string.todotask_done).toUpperCase(l);
}
return null;
}
}
}
ListFragment:
package sk.test;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import java.util.List;
import sk.test.adapter.CustomArrayAdapter;
import sk.test.task.DataListLoader;
import sk.test.xml.Item;
/**
* Created by Peter on 29.7.2013.
*/
public class TodoFragment extends ListFragment implements LoaderManager.LoaderCallbacks<List<Item>> {
public static String TASK_TYPE = "taskType";
private static final String XML_SOURCE = "http://******/";
private boolean wantDone = false;
CustomArrayAdapter mAdapter;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i("TODOLIST", "DataListFragment.onActivityCreated");
this.wantDone = getArguments().getBoolean(TASK_TYPE);
// Initially there is no data
setEmptyText("No Data Here");
// Create an empty adapter we will use to display the loaded data.
mAdapter = new CustomArrayAdapter(getActivity());
setListAdapter(mAdapter);
// Start out with a progress indicator.
setListShown(false);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
setHasOptionsMenu(true);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Insert desired behavior here.
Log.i("TODOLIST", "Item clicked: " + id);
}
#Override
public Loader<List<Item>> onCreateLoader(int i, Bundle bundle) {
Log.i("TODOLIST", "DataListFragment.onCreateLoader");
return new DataListLoader(getActivity(), this.wantDone);
}
#Override
public void onLoadFinished(Loader<List<Item>> listLoader, List<Item> items) {
mAdapter.setData(items);
Log.i("TODOLIST", "DataListFragment.onLoadFinished");
// The list should now be shown.
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
#Override
public void onLoaderReset(Loader<List<Item>> listLoader) {
}
public void reloadData(){
//UPDATE LIST.. HOW?
}
}
Loader:
package sk.test;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v4.content.AsyncTaskLoader;
import android.util.Log;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import sk.test.commons.Commons;
import sk.test.xml.Item;
import sk.test.xml.Response;
/**
* Created by Peter Chovan on 29.7.2013.
*/
public class DataListLoader extends AsyncTaskLoader<List<Item>> {
private List<Item> todoTasks;
private boolean wantDone;
SharedPreferences prefs;
public DataListLoader(Context context, boolean wantDone) {
super(context);
this.wantDone = wantDone;
prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
}
#Override
public List<Item> loadInBackground() {
Log.i("TODOLIST", "DataListLoader.loadInBackground");
String xmlData = getXmlData(prefs.getString("service_url", "http://*****/"));
List<Item> entries = new ArrayList<Item>();
String state = wantDone ? "WANT DONE" : "WANT PLANNED";
if (xmlData != null) {
xmlData = xmlData.replaceAll("<([^/]+?)/>", "<$1> </$1>");
Serializer serializer = new Persister();
try {
Response res = serializer.read(Response.class, xmlData, false);
for (Item i : res.getItems().getItem()) {
if (i.isDone() == wantDone) {
entries.add(i);
}
}
} catch (Exception e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TEST serializer", s.toString());
}
}
} else {
Log.e("TODOLIST DATA", "NULL");
}
return entries;
}
public String getXmlData(String uri) {
try {
URL url = new URL(uri);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setRequestProperty("Accept", "application/xml");
Map<String, String> params = new HashMap<String, String>();
params.put("user", prefs.getString("service_login", "devel"));
params.put("pass", prefs.getString("service_password", "devel"));
params.put("class", "GetList");
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
wr.write(Commons.getRequestData(params)); //add request params
wr.flush();
String xmlData = readStream(con.getInputStream());
wr.close();
con.disconnect();
return xmlData;
} catch (Exception e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "doInBackground" + s.toString());
}
}
return null;
}
private String readStream(InputStream in) {
BufferedReader reader = null;
String result = "";
try {
reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
result += line + "\n";
}
return result;
} catch (IOException e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "ReadStream || " + s.toString());
}
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
for (StackTraceElement s : e.getStackTrace()) {
Log.e("TODOLIST", "ReadStream || " + "Error while closing Reader");
}
}
}
}
return null;
}
/**
* Called when there is new data to deliver to the client. The
* super class will take care of delivering it; the implementation
* here just adds a little more logic.
*/
#Override
public void deliverResult(List<Item> listOfData) {
if (isReset()) {
// An async query came in while the loader is stopped. We
// don't need the result.
if (listOfData != null) {
onReleaseResources(listOfData);
}
}
List<Item> oldApps = listOfData;
todoTasks = listOfData;
if (isStarted()) {
// If the Loader is currently started, we can immediately
// deliver its results.
super.deliverResult(listOfData);
}
// At this point we can release the resources associated with
// 'oldApps' if needed; now that the new result is delivered we
// know that it is no longer in use.
if (oldApps != null) {
onReleaseResources(oldApps);
}
}
/**
* Handles a request to start the Loader.
*/
#Override
protected void onStartLoading() {
if (todoTasks != null) {
// If we currently have a result available, deliver it
// immediately.
deliverResult(todoTasks);
}
if (takeContentChanged() || todoTasks == null) {
// If the data has changed since the last time it was loaded
// or is not currently available, start a load.
forceLoad();
}
}
/**
* Handles a request to stop the Loader.
*/
#Override
protected void onStopLoading() {
// Attempt to cancel the current load task if possible.
cancelLoad();
}
/**
* Handles a request to cancel a load.
*/
#Override
public void onCanceled(List<Item> apps) {
super.onCanceled(apps);
// At this point we can release the resources associated with 'apps'
// if needed.
onReleaseResources(apps);
}
/**
* Handles a request to completely reset the Loader.
*/
#Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
// At this point we can release the resources associated with 'apps'
// if needed.
if (todoTasks != null) {
onReleaseResources(todoTasks);
todoTasks = null;
}
}
/**
* Helper function to take care of releasing resources associated
* with an actively loaded data set.
*/
protected void onReleaseResources(List<Item> apps) {
}
}
Use this to restart the Loader: getLoaderManager().restartLoader(0, null, this);
I would like to write my project in the lowest possible Android version for my reqs, which is 11.
But I need Fragment.attach and ActionBars.
Since level 11 does not include Fragment.attach I import the support package for v4.
But now the problem is that the TabListerner for the ActionTab does not use the v4 Fragment but rather the level 11 Fragment. Casting won't work.
Do I really need to switch to level 13 or is there a feasible solution to implement all this in level 11.
Here is the code:
import android.app.ActionBar;
import android.app.Activity;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.Fragment;
import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.os.Bundle;
import android.support.v4.app.Fragment;
public class TestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public static class TabListener<T extends android.support.v4.app.Fragment> /* to make sure it take the Fragment from the support package! */
implements ActionBar.TabListener {
private Fragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
/**
* Constructor used each time a new tab is created.
*
* #param activity
* The host Activity, used to instantiate the fragment
* #param tag
* The identifier tag for the fragment
* #param clz
* The fragment's Class, used to instantiate the fragment
*/
public TabListener(Activity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
/* The following are each of the ActionBar.TabListener callbacks */
public void onTabSelected(Tab tab,
android.support.v4.app.FragmentTransaction ft) {
// Check if the fragment is already initialized
if (mFragment == null) {
// If not, instantiate and add it to the activity
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, mTag);
} else {
// If it exists, simply attach it in order to show it
ft.attach(mFragment);
}
}
/* these are NOT the implementation of the TabListener above, since the use the
*
* the FragmentTransactionof the support package and not of level 11
*
*/
public void onTabUnselected(Tab tab,
android.support.v4.app.FragmentTransaction ft) {
if (mFragment != null) {
// Detach the fragment, because another one is being attached
ft.detach(mFragment);
}
}
public void onTabReselected(Tab tab,
android.support.v4.app.FragmentTransaction ft) {
// User selected the already selected tab. Usually do nothing.
}
/* these are added since they belong to the above definition of TabListener
*
* unfortunately the use the FragmentTransaction of level 11, not the one of the support package!
*
*/
#Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
}
#Override
public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {
}
#Override
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {
}
}
}
im using ActionBarCompat and Fragments on Api Ver 8.0 , the only diference with your code its that im using ft.replace instead of ft.add and a ViewPager on the xml to show the fragments, it runs ok so far ..
import android.app.Activity;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
public final class TabListener<T extends Fragment> implements ActionBar.TabListener {
private Fragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
/** Constructor used each time a new tab is created.
* #param activity The host Activity, used to instantiate the fragment
* #param tag The identifier tag for the fragment
* #param clz The fragment's Class, used to instantiate the fragment
*/
public TabListener(Activity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
/* The following are each of the ActionBar.TabListener callbacks */
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// Check if the fragment is already initialized
if (mFragment == null) {
// If not, instantiate and add it to the activity
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.replace(R.id.pager, mFragment, mTag);
} else {
// If it exists, simply attach it in order to show it
ft.replace(R.id.pager, mFragment, mTag);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
// Detach the fragment, because another one is being attached
ft.remove(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// User selected the already selected tab. Usually do nothing.
}
}
Not sure if you still need this, but we use ActionBarSherlock and it sounds like it could help you as well:
http://actionbarsherlock.com/