I took over this android project from an outsourced developer. I do iOS development so I am still trying to get up to speed with android. The app has a top tab navigation which appears on all views. The home view is a fragment which has icons which when clicked on produce webviews that replace the home view, which the navigation tab still in view. I want to replace one of the webviews with a list view which is a fragment which I already have coded (EHallSchedFragment.java), so that when the icon is clicked on the list view replaces the home view with the navigation tab still in view. See the images below.
HOME VIEW
VIEW I WANT WHEN EXHIBIT HALL SCHEDULE ICON IS CLICKED ON
Here is the code for the onClick event for that button as it exists. It calls a webView:
ivExhall.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
openInternalWebview("http://www.web.org/m/content.aspx?id=7006");
//Need code here to open EhallSchedFragment.java
}
});
SO what I need is the onClick code that will open the fragment in the existing view, leaving the navigation tab in place.
Try this approach: Define an interface inside your fragment, implement it in your activity and then override the method there. Then finally, from your fragment, when a user clicks an item from a list, call the interface method to notify the activity of the event.
From Your Fragment
#Override
public void onClick()
{
//when a user selects an event from your list
switch(position)
{
((OnScheduleSelectedListener) getActivity()).switchFragment(new DetailsFragment());
}
}
public interface OnScheduleSelectedListener
{
void switchFragment(Fragment frag);
}
You can then do the following in your activity:
public class ScheduleAppActivity extends Activity implements OnScheduleSelectedListener
{
.............................
#Override
switchFragment(Fragment frag)
{
//check if fragment is in view here and if,
replaceFragment(fragment)
//else
addFragment(frag);
commit();
}
}
So at this point, the right fragment will be added to view.
I hope this helps you!
Related
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Data data = mListDatas.get(i);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ThirdFragment thirdFragment = new ThirdFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("detail", data);
thirdFragment.setArguments(bundle);
transaction.replace(R.id.content,ThirdFragment).addToBackStack(null).commit();
BottomNavigationView navigation = (BottomNavigationView)view.findViewById(R.id.navigation_bottomview);
navigation.setSelectedItemId(R.id.navigation_third_tab);
}
});
In the above code i need to open a new fragment on the bottom tab from a list item click,
i am able to open a new fragment but the current tab remains unchanged i.e, after redirecting to the third fragment on third bottom tab ,the current tab i.e, Second Tab is active.
How can i change the active state of bottom tab from second tab to third tab on the list item click ??
Your activity needs to implement the BottomNavigationView.OnNavigationItemSelectedListener. This can be done simply by adding implements BottomNavigationView.OnNavigationItemSelectedListener after your class name, this is done so you can get the click callback whenever one of the bottom menu items are clicked on.
Then you need to override the onNavigationItemSelected function so add the following code to your activity.
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.tab_1:
handleFragmentChange(Fragment_1.newInstance());
return true;
}
return false;
}
Also add navigation.setOnNavigationItemSelectedListener(this); in the same activity once you have found the view using findViewById. This is done so that the system knows that your class is handling the event when a bottom menu is clicked so it calls the above function in your class.
The return true is what notifies the android system that it needs to switch the tab.
if this code locates in fragment then you need to replace
BottomNavigationView navigation = view.findViewById(R.id.navigation_bottomview);
navigation.setSelectedItemId(R.id.navigation_third_tab);
before
...commit();
and add getRootView() because your BottomNavigationView locate inside main container - root activity
BottomNavigationView navigation = view.getRootView().findViewById(R.id.navigation_bottomview);
navigation.setSelectedItemId(R.id.navigation_third_tab);
Suppose I am having 5 fragments in viewpager. Lets say Fragment A, B, C, D, E.
I have a button on fragment A to go to fragment B. When I press this button, viewpager scrolls to fragment B. Somehow I controlled the duration of fragment A to B. Now the thing is, I have an scrollable container in Fragment B. I want to scroll that container during the Scroll between A to B happens. Now its scrolling after I am going from Fragment A to B. I want this happen between this transition.
Inside first fragment:
#Override
public void onClick(View view) {
if(view.getId() == bottomLayout.getId())
{
MainActivity.pager.setCurrentItem(1);
}
}
It will change my pager position 0 to 1. Now when its changing. I controlled the scroll speed of viewpager. On top of second fragment, I have a ScrollView, I need to perform scroll on this scrollview as fragment is changing,not after its changed.
To animate the view of the FragmentB, you need to tell it to start animation as soon as you call viewPager.setCurrentItem().
Inside FragmentA's click listener, you will ask the parent Activity to change the ViewPager item (see Communicating with the Activity to know how this should be done) :
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
activityCallback.setViewPagerItem(POSITION_OF_FRAGMENT_B);
}
});
In your Activity in which the ViewPager resides, you will write:
public void setViewPagerItem(int position) {
viewPager.setCurrentItem(position);
// following asks the fragmentB to start its animation on its view.
if (position == POSITION_OF_FRAGMENT_B) {
fragmentB.startYourAnimation();
}
}
In FragmentB, you add a method:
public void startYourAnimation() {
// write your code to animate your ListView or whatever you want to
// animate inside the FragmentB
}
Notes:
Unless you've called viewPager.setOffscreenPageLimit(), an instance of FragmentB will already exist if you're doing it from FragmentA or FragmentC,
a Fragment should not communicate with other fragments directly, instead they should use their parent Activity as a middle person. See Communicating with Other Fragments.
No it is not possible to do so because any scrollable view like listview or recyclerview, the items are created only when it is visible to user and only when scrolled, so if that fragment is not visible, you cannot scroll any of its child scrollable view.
I am working or an app where I have 4 fragments in viewpager and floating action button (fab). When I click on fab there appear 3 subfabs. Each of them start different activities where user can search data from different fragments. Is it possible to set fab so that if I click on it while I'm in first fragment it'll open an activity for searching inside this fragment, onClick inside second - search for second and etc. The issue is that now clicking on sub fab while I'm in some fragment I can search data from another fragment too and it's a bit weird. I understand question is kinda strange, if something is unclear I'll explain further
You can make FAB button public and implement onClick listener in each fragment.
You should override setUserVisibleHint and put your code onResume so getActivity() will not return null. Fab button will have different actions in different fragments.
Here's an example, inside each fragment when you want Fab click listener:
#Override
public void setUserVisibleHint(boolean visible)
{
super.setUserVisibleHint(visible);
if (visible && isResumed())
{
onResume();
}
}
#Override
public void onResume()
{
super.onResume();
if (!getUserVisibleHint())
{
return;
}
MainActivity mainActivity = (MainActivity)getActivity();
mainActivity.fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do what you want
}
});
}
You can check in onclick method of floating action button which fragment is currently opened and calling it.
Call findFragmentById() on FragmentManager and determine which fragment is in your R.id.frameTitle container.
I have 2 viewpagers: swipeViewPager and nonSwipeViewPager in MainActivity
In swipeableViewPager, I have fragments: homeFragmentFirst and homeFragmentSecond
In nonSwipeableViewPager, I have fragments: AppleFragment , MangoFragment, GrapesFragment and CherryFragment
First I want swipeableViewPager to be viewed in MainActivity. So I have set setVisibility of nonSwipeableViewPager as GONE.
After selecting an item from the drawer, I setVisibility of swipeableViewPager as GONE and of nonSwipeableViewPager as Visible.
By this, I open AppleFragment
Situation:
Suppose, I selected Grapes from drawer, GrapesFragment opens.
I do my some stuff there. And then when I press back button, the app closes i.e. the MainActivity closes.
What I want is when back button is pressed, I want to again bring back homeFragmentFirst from swipeableViewPager.
I have tried below code in GrapesFragment
#Override
public void onBackPressed() {
super.onBackPressed();
// Do some operations here
MainActivity mainActivity = new MainActivity();
mainActivity.swipeHomeViewPager.setVisibility(View.VISIBLE);
mainActivity.nonSwipeHomeViewPager.setVisibility(View.GONE);
}
I solved it myself. I added following in MainActivity:
#Override
public void onBackPressed() {
if (nonSwipeHomeViewPager.getVisibility() == View.VISIBLE) {
nonSwipeHomeViewPager.setVisibility(View.GONE);
swipeHomeViewPager.setVisibility(View.VISIBLE);
swipeHomeViewPager.setCurrentItem(0,true);
} else if (swipeHomeViewPager.getVisibility() == View.VISIBLE){
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
}
You can implement backstack for the fragments (while adding / replacing fragment) add it to backstack. the back press will automatically take you to previous fragment.
otherwise you need to override OnBackPressed method to handle with your own logic.
I got the next FragmentActivity. This FragmentActivity inflates a layout with a LinearLayout(a menu where some buttons are defined to call other fragments) and a FrameLayout (a black space where the other fragments are loaded depending the button I select).
public class MenuViewActivity extends FragmentActivity {
....
I load the selected Fragment using onClickListener:
protected void onCreate(Bundle savedInstanceState) {
....
final OnClickListener fragment_1 = new OnClickListener() {
#Override
public void onClick(View v) {
fragment_1 Fragment = new fragment_1();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, Fragment);
transaction.addToBackStack(null);
transaction.commit();
}
};
I do this for about 5 buttons. This menu also contains a custom back key. The functionality of this back button should be like:
[fragment_1][fragmen_2][fragment_3][fragment_4][fragment_5]
The app starts always showing fragment_1. I con go from fragment_1 to any of the other fragments. So I could go for example from [fragment_1] to [fragment_4]. When pressing the back key I should go back to [fragment_1].
To detail a little bit more the functionality, I could do: [fragment_1]->[fragment_2]->[fragment_3] and when pressing back, should go back to [fragment_1].
I've got a onClickListener for the back key, but I don't know how to implement this functionality.
you're looking for this
getSupportFragmentManager().popBackStack();
also if you're unaware that's the default functionality for the actual android back button, so unless you've overrode it that will do the same thing.
You just need to pop all fragments from your backstack, unless you reach the one you want. It is probably simplest to use FragmentManager's popBackStack():
public abstract void popBackStack (int id, int flags)
Pop all back stack states up to the one with the given identifier