I have a navigation drawer and a fragment that generates a list of products. The problem is that when I click on a product it tryes to find onClick method in base activity not in fragment's java class. Should I implement onClick method in the base activity or is there any way to implement it in fragment's class.
This is product's layout "item_order.xml":
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:onClick="orderClick"
android:id="#+id/tOrder"
android:padding="4dp">
....
</RelativeLayout>
Here is the base class:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_waiter);
//set fragment
OrdersFragment fragment=new OrdersFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container,fragment);
fragmentTransaction.commit();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
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();
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, 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);
OrdersFragment.wa=this;
}
Here is the fragment:
public class OrdersFragment extends Fragment {
private Database db;
private ArrayList<Order> orders=new ArrayList<Order>();
private OrderAdapter adapter;
private ListView listOrders;
public static WaiterActivity wa;
public OrdersFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_orders, container, false);
// Inflate the layout for this fragment
db = new Database();
db.createNewOrderListener(this);
ListView listOrders = (ListView) view.findViewById(R.id.ordersList);
adapter = new OrderAdapter(this.getContext(), R.layout.item_order, orders);
listOrders.setAdapter(adapter);
return view;
}
I think you are talking about list view item selection.
Firstly remove onClick from you xml. Create a function orderClick in you base activity and Then in you fragment add onItemClick listener to your list view.
listOrders.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if (getActivity() instanceof "your base activity"){
(("your base activity")getActivity()).orderClick();
}
}
});
You should call activity method for taking action by calling it in your fragment class and pass the itemIndex of item that has been called.
use setOnItemClickListener in your activity, and call the fragments from there only, as:-
mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Fragment fragment = null;
FragmentManager fragmentManager = getSupportFragmentManager();
switch (position) {
case 0:
fragment = new ProgramFragment();
break;
case 1:
fragment = new FeedbackFragment();
break;
case 2:
fragment = new ShareFragment();
break;
case 3:
fragment = new LogOutFragment();
break;
default:
fragment =null;
}
if (fragment != null) {
fragmentManager.beginTransaction().replace(R.id.main_fragment_container, fragment).commit();
}
mDrawerList.setItemChecked(position, true);
drawerLayout.closeDrawer(mDrawerList);
}
});
Related
This is the test I am trying to do. I don't know if it can be done or not.
What I am trying to do is, when the user clicks the Navigation Drawer item, I want to change the content of the fragment. I am not using different fragments, actually I am using only one fragment.
What I want to achieve is, when the user click the drawer menu item, the fragment should display the data as per the click, for simplicity just the name of the menu item in the fragment.
With use of the single fragment, I want to have different content with the different menu item click.
The Menu items in the Navigation Drawer are dynamically created as that is intended to be shown from the db, and the number of menu items can be variable.
EDIT:
NavigationDrawerActivity
public class NavigationActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
DrawerLayout drawer;
FragmentManager fragmentManager;
Fragment testFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigation);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
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();
}
});
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
final Menu menu = navigationView.getMenu();
for (int i = 1; i <= 10; i++) {
menu.add(0,i,0,"Set "+ i);
}
fragmentManager = getSupportFragmentManager();
testFragment = new TestFragment();
}
#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();
for (int i = 0; i<10; i++) {
// Handle the camera action
if (id == i){
Bundle bundle = new Bundle();
bundle.putString("SET_ID", "this is test"+i);
// set Fragmentclass Arguments
testFragment.setArguments(bundle);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_container, testFragment).commit();
}
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
TestFragment
public class TestFragment extends Fragment {
TextView textView;
public TestFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_test, container, false);
String idValue = getArguments().getString("SET_ID");
Log.d("TEST_VALUE***", idValue);
textView = view.findViewById(R.id.just_Text);
textView.setText("Set id is: "+idValue);
return view;
}
}
Try adding the below line inside onNavigationItemSelected for lopp
testFragment = new TestFragment(); // this line
Example:
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
for (int i = 0; i<10; i++) {
// Handle the camera action
if (id == i){
Bundle bundle = new Bundle();
bundle.putString("SET_ID", "this is test"+i);
// set Fragmentclass Arguments
testFragment = new TestFragment(); // add this line in your code.
testFragment.setArguments(bundle);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_container, testFragment).commit();
}
}
Check this it might work...
In my App, I have two Fragments: FragmentA and FragmentB which are loaded from my MainActivity by the help of an SlidingMenu.
When FragmentB is shown, it immediatelly starts an AsyncTask in background to load data from a server. The loading process is reflected by an active SwipeRefreshLayout to the user.
When loading is finished, the UI of FragmentB is refreshed with the loaded data, by the help of a delegate which is passed to MyAsyncClass.
I am now facing the following problem:
As soon as processFinish in my delegate is called, I am stopping the Refresh of the SwipeRefreshLayout by the help of swipeRefreshLayout.setRefreshing(false).
If the user is going back to FragmentA while background-Task is still in progress, it appears in about 20% of the cases, that FragmentB is still in background of FragmentA in the User Interface (see Screenshot below).
As you can see in the image, the FragmentA is shown (the text "No tracks played yet" is from FragmentA), but in the background you can see still the FragmentB.
As already mentioned, this is not in 100% of the cases, so it should not be an background/transparency issue. If I comment out the swipeRefreshLayout.setRefreshing(false), then the problem is not reproductible, but somehow I need to stop the SwipeRefreshLayout in case the user stays on FragmentB.
Any idea what causes this behaviour?
AsyncResponse-Interface:
public interface AsyncResponse {
void processFinish(String result);
}
FragmentB-Class:
public class FragmentB extends MyFragment implements SwipeRefreshLayout.OnRefreshListener, AsyncResponse {
private SwipeRefreshLayout swipeRefreshLayout;
private View view;
private RecyclerView recyclerView;
public FragmentB () {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.songs_list, container, false);
swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setOnRefreshListener(this);
swipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.colorPrimary));
// Set the adapter
Context context = view.getContext();
recyclerView = (RecyclerView) view.findViewById(R.id.listinclude);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), R.drawable.divider));
List<Song> songsList = databaseHandler.getAllSongs();
setVisibilities(songsList);
this.recyclerViewAdapter = new RecyclerViewAdapter(songsList, mListener, false, false);
recyclerView.setAdapter(this.recyclerViewAdapter);
swipeRefreshLayout.setRefreshing(true);
receive();
return view;
}
private void setVisibilities(List<Song> songsList) {
ViewFlipper viewFlipper = (ViewFlipper) view.findViewById(R.id.viewFlipper);
if (songsList.isEmpty() && viewFlipper.getDisplayedChild() == 0) {
viewFlipper.setDisplayedChild(1);
} else if (!songsList.isEmpty() && viewFlipper.getDisplayedChild() == 1) {
viewFlipper.setDisplayedChild(0);
}
}
#Override
public void onRefresh() {
if (MyOnlineHelper.isOnline(getContext())) {
receive();
} else {
swipeRefreshLayout.setRefreshing(false);
}
}
private void receive() {
new MyAsyncClass(this, getContext()).execute("receiving");
}
#Override
public void processFinish(String output) {
// refreshUI
swipeRefreshLayout.setRefreshing(false);
}
}
FragmentA-Class:
public class FragmentA extends MyFragment implements AsyncResponse {
private View view;
private RecyclerView recyclerView;
public FragmentA() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
List<Song> songsList = myDatabaseHandler.getAllSongs();
view = inflater.inflate(R.layout.home_list, container, false);
// Set the adapter
Context context = view.getContext();
recyclerView = (RecyclerView) view.findViewById(R.id.listinclude);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), R.drawable.divider));
setVisibilities(songsList);
this.recyclerViewAdapter = new RecyclerViewAdapter(songsList, mListener, false, true);
recyclerView.setAdapter(this.recyclerViewAdapter);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
private void setVisibilities(List<Song> songsList) {
ViewFlipper viewFlipper = (ViewFlipper) view.findViewById(R.id.viewFlipper);
if (songsList.isEmpty() && viewFlipper.getDisplayedChild() == 0) {
viewFlipper.setDisplayedChild(1);
} else if (!songsList.isEmpty() && viewFlipper.getDisplayedChild() == 1) {
viewFlipper.setDisplayedChild(0);
}
}
#Override
public void processFinish(String output) {
// does something
}
}
MyAsyncClass:
public class MyAsyncClass extends AsyncTask<String, Integer, String> {
private AsyncResponse delegate;
private Context mContext;
private MyDatabaseHandler myDatabaseHandler;
public MyAsyncClass(AsyncResponse delegate, Context context) {
this.delegate = delegate;
this.mContext = context;
}
#Override
protected String doInBackground(String... params) {
// calling webservice and writing it to the database
}
#Override
protected void onPostExecute(String result) {
delegate.processFinish(result);
super.onPostExecute(result);
}
}
MainActivity-Class:
public class MainActivity extends AppCompatActivity implements MyFragment.OnListFragmentInteractionListener, AsyncResponse {
private FragmentA fragmentA = new FragmentA();
private FragmentB fragmentB;
private NavigationView navigationView;
private DrawerLayout drawer;
private Toolbar toolbar;
// index to identify current nav menu item
private static int navItemIndex = 0;
public static String CURRENT_TAG = MyConstants.TAG_FRAGMENT_A;
// toolbar titles respected to selected nav menu item
private String[] activityTitles;
// flag to load home fragment when user presses back key
private Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentA.setDatabaseHandler(this.myDatabaseHandler);
// Init UI
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mHandler = new Handler();
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.nav_view);
fabSendButton = (FloatingActionButton) findViewById(R.id.fab);
// Navigation view header
navHeader = navigationView.getHeaderView(0);
// load toolbar titles from string resources
activityTitles = getResources().getStringArray(R.array.sliding_menu_item_activity_titles);
// initializing navigation menu
setUpNavigationView();
if (savedInstanceState == null) {
navItemIndex = 0;
CURRENT_TAG = MyConstants.TAG_FRAGMENT_A;
loadHomeFragment();
}
}
/***
* Returns respected fragment that user
* selected from navigation menu
*/
private void loadHomeFragment() {
// set toolbar title
setToolbarTitle();
// if user select the current navigation menu again, don't do anything
// just close the navigation drawer
if (getSupportFragmentManager().findFragmentByTag(CURRENT_TAG) != null) {
drawer.closeDrawers();
return;
}
// Sometimes, when fragment has huge data, screen seems hanging
// when switching between navigation menus
// So using runnable, the fragment is loaded with cross fade effect
// This effect can be seen in GMail app
Runnable mPendingRunnable = new Runnable() {
#Override
public void run() {
// update the activity_main_header_with_item content by replacing fragments
Fragment fragment = getFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
fragmentTransaction.replace(R.id.frame, fragment, CURRENT_TAG);
fragmentTransaction.commit();
}
};
// If mPendingRunnable is not null, then add to the message queue
if (mPendingRunnable != null) {
mHandler.post(mPendingRunnable);
}
//Closing drawer on item click
drawer.closeDrawers();
// refresh toolbar menu
invalidateOptionsMenu();
}
private Fragment getFragment() {
switch (navItemIndex) {
case 0:
return this.fragmentA;
case 1:
if (fragmentB == null) {
fragmentB = new FragmentB();
fragmentB.setDatabaseHandler(this.myDatabaseHandler);
}
return fragmentB;
default:
return this.fragmentA;
}
}
private void setToolbarTitle() {
getSupportActionBar().setTitle(activityTitles[navItemIndex]);
}
private void setUpNavigationView() {
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()) {
//Replacing the activity_main_header_with_item content with ContentFragment Which is our Inbox View;
case R.id.nav_A:
navItemIndex = 0;
CURRENT_TAG = MyConstants.TAG_FRAGMENT_A;
break;
case R.id.nav_B:
navItemIndex = 1;
CURRENT_TAG = MyConstants.TAG_FRAGMENT_B;
break;
default:
navItemIndex = 0;
}
loadHomeFragment();
return true;
}
});
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.openDrawer, R.string.closeDrawer) {
#Override
public void onDrawerClosed(View drawerView) {
// Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
super.onDrawerClosed(drawerView);
}
#Override
public void onDrawerOpened(View drawerView) {
// Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank
super.onDrawerOpened(drawerView);
}
};
//Setting the actionbarToggle to drawer layout
drawer.setDrawerListener(actionBarDrawerToggle);
//calling sync state is necessary or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main_header_with_item, menu);
return true;
}
}
Thanks to Prsnth Gettin High and this post ( When switch fragment with SwipeRefreshLayout during refreshing, fragment freezes but actually still work), wrapping the SwipeRefreshLayout in a FrameLayout helps, like that:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewFlipper
android:id="#+id/viewFlipper"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/listinclude"
layout="#layout/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:visibility="visible"/>
<include
android:id="#+id/emptyinclude"
layout="#layout/fragment_empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"/>
</ViewFlipper>
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
try downcasting the fragment object to the specific fragment.
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
Fragment fragment = getFragment();
FragmentA fragA;
FragmentB fragB;
if(fragment intanceof FragmentA)
{
fragA=(FragmentA) fragment;
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
fragmentTransaction.replace(R.id.frame, fragA, FragmentA.TAG);
}
if(fragment instanceof FragmentB)
{
fragB=(FragmentB) fragment;
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
fragmentTransaction.replace(R.id.frame, fragB, FragmentB.TAG);
}
fragmentTransaction.commit();
And may I ask why are you using a runnable to swap fragments?
try reusing the view. It may fix the issue.
`#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(view==null){view = inflater.inflate(R.layout.songs_list, container, false);}`
A fragment named NewsCenterFragment would replace the FramLayout in DrawerActivity.The problem is program will crash when I swipe the viewPager to a next slide. The exception is given which says: java.lang.IllegalStateException: The specified child already has a parent.You must call removeView() on the child's parent first.
public class DrawerActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener,Serializable {
private FragmentManager fm;
private NavigationView navigationView;
private NewsMenu data;
private RadioGroup radioGroup;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
radioGroup = (RadioGroup) findViewById(R.id.content_drawer_radioGroup);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
checkCacheForNewsCenterSlideBar();
changeNewsSlideBar();
Fragment homeFragment = new HomeFragment();
fm = getFragmentManager();
fm.beginTransaction().replace(R.id.content_drawer_content,homeFragment).commit();
getSupportActionBar().setTitle("Home page");
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId){
case R.id.content_drawer_radioGroup_shouye:
Fragment homeFragment = new HomeFragment();
fm.beginTransaction().replace(R.id.content_drawer_content,homeFragment).commit();
getSupportActionBar().setTitle("Home page");
break;
case R.id.content_drawer_radioGroup_newscenter:
Fragment newsCenterFragment = new NewsCenterFragment(findNewsTabTitle(),DrawerActivity.this);
fm.beginTransaction().replace(R.id.content_drawer_content,newsCenterFragment).commit();
getSupportActionBar().setTitle("News center");
break;
case R.id.content_drawer_radioGroup_smartservice:
break;
case R.id.content_drawer_radioGroup_goveraffairs:
break;
case R.id.content_drawer_radioGroup_setting:
break;
}
}
});
}
public class NewsCenterFragment extends Fragment {
private ViewPager viewPager;
private Activity mActivity;
private ArrayList<String> title;
private ArrayList<View> views;
public NewsCenterFragment(ArrayList<String> title, Activity activity){
this.title = title;
this.mActivity = activity;
}
#Override
public View onCreateView(LayoutInflater layoutInflater, ViewGroup container, Bundle savedInstanceState) {
LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(mActivity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.fragment_newscenter_layout,container,false);
viewPager = (ViewPager) view.findViewById(R.id.fragment_newscenter_viewPager);
views = new ArrayList<View>();
View tempLayout = inflater.inflate(R.layout.news_title_layout,container,false);
for(int i=0;i<title.size();i++){
views.add(tempLayout);
}
viewPager.setAdapter(new NewsMenuDetailAdapter());
return view;
}
class NewsMenuDetailAdapter extends PagerAdapter{
#Override
public int getCount() {
return views.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view==(LinearLayout)object;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
String tabTitle = title.get(position);
View view = views.get(position);
TextView textView = (TextView) view.findViewById(R.id.news_title_layout_title);
textView.setText(tabTitle);
container.addView(view);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout)object);
}
}
}
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
I have been searching solution for a couple of hours.Please help me out.Thanks a lot.
It's looked like you have N references to one object in your views array from here:
View tempLayout = inflater.inflate(R.layout.news_title_layout,container,false);
for(int i=0;i<title.size();i++){
views.add(tempLayout);
}
So when your adapter started to return items it attached this view (tempLayout) for first time succesfully, but on the second it failed, because tempLayout (i.e. views[i]) already have a parent from previous call instantiateItem.
You should either provide another inflated view or call ((ViewGroup)child.getParent()).removeView(child) before call container.add()
please help me i am new to android.
I can display toast by clicking item in navigation drawer but how can i open new fragment from navigation drawer.
My code in NavigationDrawerFragment is
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
recyclerView = (RecyclerView) layout.findViewById(R.id.drawerList);
adapter = new EduAdapter(getActivity(), getData());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
Toast.makeText(getActivity(), "On click " + position, Toast.LENGTH_LONG).show();
mDrawerLayout.closeDrawer(GravityCompat.START);
Toast.makeText(getActivity(), "On Long click " + position, Toast.LENGTH_LONG).show();
}
#Override
public void onLongClick(View view, int position) {
Toast.makeText(getActivity(), "On long click " + position, Toast.LENGTH_LONG).show();
}
}));
return layout;
}
and in main activity is :
public class MainActivity extends ActionBarActivity {
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_appbar);
toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
NavigationDrawerFragment drawerFragment =
(NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), toolbar);
}
#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;
}
please help me to open new fragment from drawer as i can only display toast.
i wqas following Slidenerd Material design Video .
Create a class which extends Fragment Activity and then you can open the new fragment as shown below from the new class:
DetailViewFragment f1 = new DetailViewFragment();
getSupportFragmentManager().beginTransaction().add(R.id.fragment_layout, f1).commit();
In your onItemClicked method Navigate to the class created.
Hope this helps you.
On Your RecyclerView's item click you simply have to add the corresponding fragment this way.
getSupportFragmentManager()
.beginTransaction()
.replace(your_container_id,
new YourFragment(), YOUR_FRAGMENT_STRING_TAG)
.commit();
Please keep in mind that for each position click of the recyclerview you will add your fragment in the above way. You can probably use switch cases inside your onItemClick of the recyclerView.
See if it helps you!!! Tell me if you need any other help!!
Create a method and pass the item position in Recylerview's onitemclicklistener
public void changeFragment(int position) {
switch (position) {
case 0:{ getSupportFragmentManager().beginTransaction().replace(R.id.container, calenderFragment).setTransition (FragmentTransaction.TRANSIT_FRAGMENT_OPEN).addToBackStack(null).commit();
break;
}
case 1:{ getSupportFragmentManager().beginTransaction().replace(R.id.container, new PatientProfileFragment()).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).addToBackStack(null).commit();
break;
}
}
}
this is the first application I am creating using a NavigationDrawer. I have a pretty simple question. How do I make the first page in the NavigationDrawer the main one? Also I'm not too familiar with formatting since this is my first time using the drawer so I would appreciate it if someone more familiar could tell me if I am doing it correctly. Right now each page just displays text but eventually it will do more. And one of my questions is how do I make it so that clicking a page in the drawer can open up a new page using a RelativeLayout for example. From my understanding Adapters are only for Views, would I create a completely new activity and call startActivity() in my iteration for the drawerclick? If so, is that efficient? Meaning will it take a long time for the page to load? My main activity is:
public class MainActivity extends Activity {
private String[] mPages;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawer_layout);
mPages = getResources().getStringArray(R.array.page_titles);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mPages));
mTitle = mDrawerTitle = getTitle();
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer, R.string.drawer_open,
R.string.drawer_close) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
/** Swaps fragments in the main content view */
private void selectItem(int position) {
// Create a new fragment and specify the planet to show based on position
Fragment fragment;
if(position == 0){
fragment = new OneFragment();
// Insert the fragment by replacing any existing fragment
android.app.FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
}
else if(position == 1){
fragment = new TwoFragment();
// Insert the fragment by replacing any existing fragment
android.app.FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
}
else if(position == 2){
fragment = new ThreeFragment();
// Insert the fragment by replacing any existing fragment
android.app.FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
}
else if(position == 3){
fragment = new FourFragment();
// Insert the fragment by replacing any existing fragment
android.app.FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
}
// Highlight the selected item, update the title, and close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mPages[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
public static class OneFragment extends Fragment{
public OneFragment(){
}
View rootView;
TextView text;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup contatiner,
Bundle savedInstanceState){
rootView = inflater.inflate(R.layout.drawer_layout,
contatiner, false);
text = (TextView)rootView.findViewById(R.id.text_view1);
text.setText("One");
return rootView;
}
}
public static class TwoFragment extends Fragment{
public TwoFragment(){
}
View rootView;
TextView text;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup contatiner,
Bundle savedInstanceState){
rootView = inflater.inflate(R.layout.drawer_layout,
contatiner, false);
text = (TextView)rootView.findViewById(R.id.text_view1);
text.setText("Two");
return rootView;
}
}
public static class ThreeFragment extends Fragment{
public ThreeFragment(){
}
View rootView;
TextView text;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup contatiner,
Bundle savedInstanceState){
rootView = inflater.inflate(R.layout.drawer_layout,
contatiner, false);
text = (TextView)rootView.findViewById(R.id.text_view1);
text.setText("Three");
return rootView;
}
}
public static class FourFragment extends Fragment{
public FourFragment(){
}
View rootView;
TextView text;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup contatiner,
Bundle savedInstanceState){
rootView = inflater.inflate(R.layout.drawer_layout,
contatiner, false);
text = (TextView)rootView.findViewById(R.id.text_view1);
text.setText("Four");
return rootView;
}
}
}
I apologize for the lengthy question, but the developer site wasn't helping out too much and I want to make sure I do this correctly the first time so I don't have to go back too much
Whatever you want to show needs to be within the child of the DrawerLayout. In your case, I think you would do a fragment transaction in onCreate() to put whatever fragment you want visible first inside of the content area.
if (savedInstanceState == null) {
fragment = new OneFragment();
// Insert the fragment by replacing any existing fragment
getFragmentManager().beginTransaction()
.replace(R.id.content_frame, fragment).commit();
}
You can hold references to these fragments so you don't create a new instance of them each time the user makes a selection. You probably also want to make sure the new selection isn't the same as the current one, or else you will have extra transactions you don't need.
For opening a "new page", you want to use startActivity() and show another activity with it's own layout. Generally speaking, don't be concerned about how long it takes an Activity to load unless you are specifically doing some meaningful work (like loading a bunch of data out of a database).
Lastly, Adapters are specifically for AdapterViews (like ListView) and are an entirely different matter. They are used in conjunction with specific UI components to generate child views for representing potentially large data sets and which can be recycled for efficiency reasons. I suggest you watch The World of ListView if you want more information/clarity about that.