I am using http://www.androidhive.info/2013/10/android-tab-layout-with-swipeable-views-1/ to make Tab bar.I have also 3 tab first and the second Tab view contains a List view and third on e is Settings. Settings Contain Reload button. When I clicked the Reload Button I want to move to First Tab.How can I do this ?
Make following changes:
Pass the viewPager reference to your adapter and from adapter to your fragment:
public class TabsPagerAdapter extends FragmentPagerAdapter {
ViewPager viewPager;
public TabsPagerAdapter(FragmentManager fm,ViewPager viewPager) {
super(fm);
this.viewPager=viewPager;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new TopRatedFragment(viewPager);
case 1:
// Games fragment activity
return new GamesFragment(viewPager);
case 2:
// Movies fragment activity
return new MoviesFragment(viewPager);
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
In fragment on click of button call set selection on view pager object:
public class MoviesFragment extends Fragment {
private ViewPager viewPager;
public MoviesFragment (ViewPager viewPager;){
this.viewPager=viewPager;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movies, container, false);
rootView.findViewById(<your button>).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
viewPager.setCurrentItem(0);
}
});
return rootView;
}
}
I know its quite late ....maybe it can help someone else...creating a constructor in fragments is not supported..so instead of passing viewpager as constructor..
we can write in the fragment on button click:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by medha singh on 6/17/2016.
*/
public class Fragment4 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
final View view1 = inflater.inflate(R.layout.new_lead2, container, false);
TextView tv=(TextView)view1.findViewById(R.id.hardware);
final ViewPager pager= (ViewPager)getActivity().findViewById(R.id.pager2);
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pager.setCurrentItem(1);
}
});
return view1;
}
}
So getactivity() is the solution: i got it from here: How to go other Tabs by clicking on a Button from the current Tab in Android?
Do this:
btn.setOnClickListener(new OnClickListener()
{
onClick(View v)
{
//Reload the data
tabHost.setCurrentTab(/*destination-tab-id*/);
}
}
)
Related
So,I have this activity which has tabs with listviews in them, and the problems I'm facing are:
The first and second tabs are having the same content i.e. the content the second tab should have is in first and second tab.
The third tab has correct content, though this is because it only instantiates just first and second tabs initially.
When I set
mViewPager.setOffscreenPageLimit(2);
all the three tabs have same content, which is that of the third tab.
But after i've scrolled to third tab and then scroll back to the first one, the first one refreshes and has correct content.
Also, the next problem is the second tab never refreshes,because its always on the right or left to the tab which is opened.
I want the tabs to refresh every time they are opened since i'll be constantly changing the material in the lists.
package com.towntrot.anil.towntrot_eventmanager_02;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class SlidingTabsBasicFragment extends Fragment {
ListView list;
public ArrayList<ListModel> CustomListViewValuesArr = new ArrayList<ListModel>();
public guestlist gg;
private SlidingTabLayout mSlidingTabLayout;
private ViewPager mViewPager;
private String[] eventtype={"CHECKED IN","CHECKED OUT","WAITING"};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_sample, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
mViewPager.setAdapter(new SamplePagerAdapter());
mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setViewPager(mViewPager);
}
class SamplePagerAdapter extends PagerAdapter {
#Override
public int getCount() {
return 3;
}
#Override
public boolean isViewFromObject(View view, Object o) {
return o == view;
}
#Override
public CharSequence getPageTitle(int position) {
return eventtype[position];
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View view = getActivity().getLayoutInflater().inflate(R.layout.pager_item,
container, false);
guestlist gg=(guestlist)getActivity();
StringBuilder sb = new StringBuilder();
sb.append("");
sb.append(position);
String strI = sb.toString();
Toast.makeText(getActivity(),strI,Toast.LENGTH_LONG).show();
setListData(gg.getNamelist(), gg.getStatuslist(), gg.getNo0fPeople(), position);
list= ( ListView )view.findViewById(R.id.list);
CustomAdapter adapter;
adapter=new CustomAdapter( getActivity(), CustomListViewValuesArr);
list.setAdapter(adapter);
container.addView(view);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
public void setListData(String[] string,String[] status,int no,int pos) {
CustomListViewValuesArr.clear();
for (int i = 0; i < no; i++) {
final ListModel name = new ListModel();
int x=Integer.parseInt(status[i]);
if(pos==x){ name.setCompanyName(string[i]);
CustomListViewValuesArr.add(name);}
}
}
}
Please help me, I've seen a lot of answers but couldn't solve this. Any help is appreciated.
The problem is you are calling setListData every time a pager item is intantiated, which in turn populates the CustomListViewValuesArr with data of the given position. Then your list adapters are directly using this array cause it's defined in your fragment and depending on the last instantiated item, it's contents change.
Change CustomListViewValuesArr to a local variable; create a new ArrayList<ListModel> object in your setListData method and return it, use the returned object as your CustomAdapter constructor parameter.
I have a supported fragment activity which will load diff fragments. The fragment has some textView with id = "score" and I want to get its handle but findViewById for score's textView returns null. Why so?
textView is placed in fragment
public class MyActivity extends extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks{
private TextView scoreBoardTextView = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
scoreBoardTextView = (TextView) findViewById(R.id.score); //this returns null
}
#Override
public void onNavigationDrawerItemSelected(int position) {
//set fragment
}
}
Note:
Directly accessing fragment's views outside fragment is not a good idea. You should use fragment callback interfaces to handle such cases and avoid bugs. The following way works but it is not recommended as it is not a good practice.
If you want to access the TextView of Fragment inside its parent Activity then you should define a method inside your Fragment class like this:
public class MyFragment extends Fragment {
TextView mTextView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main, container, false);
mTextView = (TextView) view.findViewById(R.id.textView1);
return view;
}
public void setTextViewText(String value){
mTextView.setText(value);
}
}
Now you can use this inside your Activity like this:
myFragment.setTextViewText("foo");
here myFragment is of type MyFragment.
If you want to access the whole TextView then you can define a method like this inside MyFragment.java:
public TextView getTextView1(){
return mTextView;
}
By this you can access the TextView itself.
Hope this Helps. :)
It is possible with following way:
Keep reference of inflated view in the Fragment like this :
public class MyFragment extends SherlockFragment{
MainMenuActivity activity;
public View view;
public MyFragment(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if ( getActivity() instanceof MainMenuActivity){
activity = (MainMenuActivity) getActivity();
}
view = inflater.inflate(R.layout.aboutus, container, false);
return view;
}
}
Create a function in the Activity, like this:
public class MainMenuActivity extends SherlockFragmentActivity {
SherlockFragment fragment = null;
public void switchContent(SherlockFragment fragment) {
this.fragment = fragment;
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.mainmenu, fragment)
.commit();
invalidateOptionsMenu();
}
Its purpose is to keep reference of current fragment. Whenever you wanna switch fragment, you call above function, like this (from fragment):
activity.switchContent( new MyFragment_2());
Now you've current fragment reference. So you can directly access Fragment's views in Activity like this: this.fragment.view
You have no need of reference of Fragment view to get its components in Activity. As you can directly access layout components of a Fragment in parent Activity.
Simply you can access any component by this
findViewById(R.id.child_of_fragment_layout);
In order to access the TextView or Button or whatever in your fragment you need to do the following:
public class BlankFragment extends Fragment {
public View view;
public TextView textView;
public Button button;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view =inflater.inflate(R.layout.fragment_blank, container, false);
textView = (TextView)view.getRootView().findViewById(R.id.textView_fragment1);
return view;
}
public void changeTextOfFragment(String text){
textView.setText(text);
view.setBackgroundResource(R.color.colorPrimaryDark);
}
Once that is done in your MainActivity or any other where you want to access your TextView from your Fragment you should make sure to set up the fragment in your OnCreate() method other ways it will most likely throw nullPointer. So your activity where you want to change the TextView should look smth like this:
public class MainActivity extends AppCompatActivity {
private Button button1;
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
BlankFragment blankFragment = new BlankFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button)findViewById(R.id.button1);
changeFragment();
fragmentManager = getFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment1,blankFragment);
fragmentTransaction.commit();
}
private void changeFragment(){
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
blankFragment.changeTextOfFragment("Enter here the text which you want to be displayed on your Updated Fragment");
}
});
}
Hope this helps :)
You can access with getView method of Fragment class.
For example You have a TextView in Your MyFragment with id of "text_view" In Your Activity make a Fragment of Yours:
MyFragment myFragment = new MyFragment();
And when You need a child just call getView and then find Your childView.
View view = myFragment.getView();
if (view !=null) {
view.findViewById(R.id.text_view).setText("Child Accessed :D");
}
Note: if you want the root view of your fragment, then myFragment.getView(); is simply enough.
Just put in fragment instead of putting in activity:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_new_work_order,
container, false);
TextView scoreBoardTextView = (TextView) rootView.findViewById(R.id.score);
return rootView;
}
Only doing this:
((Your_Activity) this.getActivity()).YouyActivityElements;
If your TextView placed inside Fragment that case you cannot access TextView inside your Fragment Parent Activity you can set the interface for intercommunication between Fragment and Activity and send Data when you click on TextView or anyother thing which you want to happend
You can't access Fragment element in Parent Activity, But You can pass values to your Fragment by following way.
in your onNavigationDrawerItemSelected method of MyActivity do the following
int myScore = 100;
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.container,
MyFragment.newInstance(myScore)).commit();
}
And in MyFragment class create a method called newInstance like following
private static final String SCORE = "score";
public static MyFragment newInstance(int score) {
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putInt(SCORE, score);
fragment.setArguments(args);
return fragment;
}
And in MyFragment's onCreateView() method
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
TextView textView = (TextView) rootView
.findViewById(R.id.score);
textView.setText(Integer.toString(getArguments().getInt(
SCORE)));
return rootView;
}
That's All, I hope this will help you. If not please let me know.
The score textView is in the layout of fragment, it's not in the layout of the MyActivity, i.e. R.layout.activity_home. So you could find the score textview in that fragment once you inflate the corresponding layout file.
It returns null cause the TextView is an element of the Fragment, not the Activity.
Please note that the idea of using Fragment is to encapsulate a module inside the Fragment, which means the Activity should not have direct access to it's properties. Consider moving your logic where you get the TextView reference inside the Fragment
Simply declare TextView as public in fragment, initialize it by findViewById() in fragment's onCreateView(). Now by using the Fragment Object which you added in activity you can access TextView.
You need to call method findViewById from your fragment view.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
scoreBoardTextView = (TextView) mNavigationDrawerFragment.getView().findViewById(R.id.score);
}
This way works for me.
I suggest you to make the textview part of your activity layout. Alternately you can have the textview as a separete fragment. Have a look at my question here. Its similar to yours but in reverse direction. Here's a stripped down version of code I used in my project. The explanation are along the code.
The Activity Class
public class MainActivity extends ActionBarActivity {
PlaceFragment fragment;
TextView fragmentsTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Bundle bundle = new Bundle();
bundle.putString("score", "1000");
fragment = PlaceFragment.newInstance(bundle);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container, fragment);
ft.addToBackStack(null);
ft.commit();
// method 1
// fragment is added some ways to access views
// get the reference of fragment's textview
if (fragment.getTextView() != null) {
fragmentsTextView = fragment.getTextView();
}
// method 2
// using static method dont use in production code
// PlaceFragment.textViewInFragment.setText("2000");
// method 3
// let the fragment handle update its own text this is the recommended
// way wait until fragment transaction is complete before calling
//fragment.updateText("2000");
}
}
The fragment class:
public class PlaceFragment extends Fragment {
public TextView textViewInFragment;// to access via object.field same to
// string.length
// public static TextView textViewInFragment;//to access via
// PlaceFragment.textView dont try this in production code
public PlaceFragment() {
}
public static PlaceFragment newInstance(Bundle bundle) {
PlaceFragment fragment = new PlaceFragment();
fragment.setArguments(bundle);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment_place, container, false);
textViewInFragment = (TextView) view
.findViewById(R.id.textViewInFragment);
return view;
}
#Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
if (getArguments() != null) {
textViewInFragment.setText(getArguments().getString("score"));
}
}
public TextView getTextView() {
if (textViewInFragment != null) {
return textViewInFragment;// returns instance of inflated textview
}
return null;// return null and check null
}
public void updateText(String text) {
textViewInFragment.setText(text);// this is recommended way to alter
// view property of fragment in
// activity
}
}
Communication from activity to fragment is straight forward. This is because activity contains fragment. Keep the fragment object and access its property via setters and getters or the public fields inside it. But communication from fragment to activity requires an interface.
why you don't access it directly from your FragmentPagerAdapter,
SubAccountFragment subAccountFragment = (SubAccountFragment) mSectionsPagerAdapter.getItem(1);
subAccountFragment.requestConnectPressed(view);
and here is the full example:
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Locale;
public class TabsActivity 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.
*/
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs);
// 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 three
// 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.Tab tab = actionBar.newTab();
View tabView = this.getLayoutInflater().inflate(R.layout.activity_tab, null);
ImageView icon = (ImageView) tabView.findViewById(R.id.tab_icon);
icon.setImageDrawable(getResources().getDrawable(mSectionsPagerAdapter.getPageIcon(i)));
TextView title = (TextView) tabView.findViewById(R.id.tab_title);
title.setText(mSectionsPagerAdapter.getPageTitle(i));
tab.setCustomView(tabView);
tab.setTabListener(this);
actionBar.addTab(tab);
}
}
#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_tabs, 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_logout) {
finish();
gotoLogin();
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 ProfileFragment profileFragment;
public SubAccountFragment subAccountFragment;
public ChatFragment chatFragment;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
profileFragment = new ProfileFragment();
subAccountFragment = new SubAccountFragment();
chatFragment = new ChatFragment();
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return profileFragment;
case 1:
return subAccountFragment;
case 2:
return chatFragment;
}
return null;
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#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);
}
return null;
}
public int getPageIcon(int position) {
switch (position) {
case 0:
return R.drawable.tab_icon_0;
case 1:
return R.drawable.tab_icon_1;
case 2:
return R.drawable.tab_icon_2;
}
return 0;
}
}
public void gotoLogin() {
Intent intent = new Intent(this, LoginActivity.class);
this.startActivity(intent);
}
public void requestConnectPressed(View view){
SubAccountFragment subAccountFragment = (SubAccountFragment) mSectionsPagerAdapter.getItem(1);
subAccountFragment.requestConnectPressed(view);
}
}
If the view is already inflated (e.g. visible) on the screen then you can just use findViewById(R.id.yourTextView) within the activity as normal and it will return the handle to the text view or null if the view was not found.
I just use methods to access fragment views from parent activity, because we create a new fragment class object to insert the fragment. So I do like this.
class BrowserFragment : Fragment(), Serializable {
private lateinit var webView: NestedScrollWebView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
webView = view.findViewById(R.id.web_view)
}
fun getWebView(): WebView {
return webView
}
}
In MainActivity
val browserFragment = BrowserFragment()
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.add(R.id.browser_fragment_placeholder, browserFragment)
fragmentTransaction.commit()
val webView = browserFragment.getWebView()
I have followed a tutorial to create step by step a sliding menu and it works, but looking in the code I have noticed that when users touch a menu item the code will run this piece of code:
MainActivity:
....
/**
* Slide menu item click listener
* */
private class SlideMenuClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// display view for selected nav drawer item
displayView(position);
}
}
/**
* Diplaying fragment view for selected nav drawer list item
* */
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:{
fragment = new PersonaggiPrincipali();
break;
}
case 1:{
fragment = new PersonaggiSecondari();
break;
}
case 2:{
fragment = new Video();
break;
}
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
....
Basically it call a new Class when the item is clicked.
The class is formed in this way:
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class PersonaggiPrincipali extends Fragment {
public PersonaggiPrincipali(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.personaggi_principali, container, false);
return rootView;
}
}
So it just return the layout and the displayView function above will replace the current with the returned one, right?
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
....
}
My question is, in the view returned how can I manipulate it if the class is just a return of the layout?
For example, let's assume that in the returned view I have a Button and I need to set a ClickListener or just create a function that will chenge the Activity (activity that should be insert in the main view with the SlidingMenu), How can I do that?
Should I write all the code in the MainActivity to manage that?
Ciao Christian, when you instantiate a Fragment you don't get a view as a result but a Fragment.
The onCreateView method is just part of the lifecycle of a fragment and that's where you have to return the main view of your fragment. Also, if your fragment has a Button you can set the listener in the onCreateView method of the Fragment.
http://developer.android.com/reference/android/app/Fragment.html#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
Example:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.personaggi_principali, container, false);
Button button = (Button) rootView.findViewById(R.id.REPLACE_WITH_YOUR_BUTTON_ID);
button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
// do you stuff here...
}
});
return rootView;
}
Please notice the Button in the example is just a local variable, if you need to access it later, it's better to declare it as a class variable.
Regarding communication (Fragment to Fragment, host Activity to Fragment), I think everything you need to know is well explained in the official documentation: http://developer.android.com/training/basics/fragments/communicating.html
You can either do it in the same (onCreateView()) method. Additionally, you could include private references to Views inside your fragment layout in your PersonaggiPrincipali class. Also implement get() methods for these Views and you can change them from your MainActivity.
For example:
public class PersonaggiPrincipali extends Fragment {
private Button fragButton;
public PersonaggiPrincipali(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.personaggi_principali, container, false);
fragButton = (Button) rootView.findViewById(R.id.fragButtonId); //replace R.id.fragButtonId with the appropriate Id from your xml layout
return rootView;
}
public Button getFragButton() {
return this.fragButton;
}
}
I have a android application using a pager as navigation. For the tabs I have 3 layouts as content. On one of the fragments is a gallery and I want to add images to it. For that I have to set an ImageAdapter but I need to know how to access the context of a fragment.
final LayoutInflater factory = getLayoutInflater();
final View view = factory.inflate(R.layout.pictures, null);
Gallery g = (Gallery) view.findViewById(R.id.gallery1);
g.setAdapter(new ImageAdapter(view.getContext()));
I use this code above in the onCreate method to get the gallery from a layout that is not the contentview.
I have to give a Context to the ImageAdapter. But what context do I have to set there?
EDIT: This is my complete code:
package com.bw2801.uwelugemediathek;
import java.util.Locale;
import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.content.Context;
import android.database.DataSetObserver;
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.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.SpinnerAdapter;
import android.widget.Toast;
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
PicturesSectionFragment ps = new PicturesSectionFragment();
#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));
}
final LayoutInflater factory = getLayoutInflater();
final View view = factory.inflate(R.layout.pictures, null);
Gallery g = (Gallery) view.findViewById(R.id.gallery1);
g.setAdapter(new ImageAdapter(ps.getActivity()));
}
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private Integer[] mImageIds = {
R.drawable.image01,
R.drawable.image02,
R.drawable.image03,
R.drawable.image04,
R.drawable.image05,
R.drawable.image06,
R.drawable.image07,
R.drawable.image08,
};
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mImageIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i = new ImageView(mContext);
i.setImageResource(mImageIds[position]);
i.setLayoutParams(new Gallery.LayoutParams(150, 100));
i.setScaleType(ImageView.ScaleType.FIT_XY);
return i;
}
}
#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 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) {
switch(position) {
case 0:
return new DummySectionFragment();
case 1:
return new SoundSectionFragment();
case 2:
return ps;
}
return new DummySectionFragment();
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Informationen";
case 1:
return "Soundboard";
case 2:
return "Galerie";
}
return null;
}
}
public static class DummySectionFragment extends Fragment {
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.info, container, false);
}
}
public static class PicturesSectionFragment extends Fragment {
public PicturesSectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.pictures, container, false);
}
}
public static class SoundSectionFragment extends Fragment {
public SoundSectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.sounds, container, false);
}
}
}
Fragments don't have their own Context, they use parent Activity.
To get parent Activity Context, use getActivity()
To use Application Context, use getActivity().getApplicationContext()
Prefer Application Context wherever possible.
UPDATE:
getActivity() of a Fragment returns an Activity instance if and only if, the said Fragment is currently attached to an Activity.
So,
Fragment f = new MyFragment();
creates a fragment, but it is not attached to an activity yet. Hence f.getActivity() returns null.
After its added to an activity:
getFragmentManager().beginTransaction().add(f,"fragment").commit();
Now, getActivity() will return an Activity instance.
Again, if we detach the fragment from Activity:
getFragmentManager().beginTransaction().detach(f).commit()
getActivity() will again return a null value.
So, we should not use getActivity() outside the Fragment class, because we can't be sure of attached status. Thus I'll advice you to used getActivity() inside the fragment's own class in its methods: onAttach(), onCreate() or onActivityCreated().
you can use like this
g.setAdapter(new ImageAdapter(getActivity()));
The easiest and most precise way to get the context of the fragment that I found is to get it directly from the ViewGroup when you call onCreateView method at least here you are sure not to get null for getActivity()
public class Animal extends Fragment {
Context thiscontext;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
thiscontext = container.getContext();
write under code in Your CoreApplication.java
step1)
public class CoreApplication extends Application {
private static CoreApplication instance;
}
step2) onCreate(){
instance = this;
}
step3 )
add under method()
public static CoreApplication getGlobalApplicationContext() {
if (instance == null) {
throw new IllegalStateException("this application does not
inherit GlobalApplication"); " +
"}
return instance;
}
Step4)
g.setAdapter(new ImageAdapter(getGlobalApplicationContext()));
Im trying to make an app that have the navigation type of swiping.
This is how far I have gone:
Fragment activity:
package com.app.BoomBase;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment_control extends Fragment {
String tag = this.getClass().getSimpleName();
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(tag, "onCreate");
super.onCreate(savedInstanceState);
/** Getting the arguments to the Bundle object */
Bundle data = getArguments();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.i(tag, "onCreateView");
View view = inflater.inflate(R.layout.fragment_controle,container, false );
return view;
}
}
FragmentPageAdapter:
package com.app.BoomBase;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class Fragment_Pager extends FragmentPagerAdapter {
final int PAGE_COUNT = 3;
public Fragment_Pager(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
#Override
public Fragment getItem(int arg0) {
Fragment_control myFragment = new Fragment_control();
Bundle data = new Bundle();
data.putInt("current_page", arg0+1);
myFragment.setArguments(data);
return myFragment;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return PAGE_COUNT;
}
}
MainActivity:
package com.app.BoomBase;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends FragmentActivity {
String tag = this.getClass().getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(tag, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/** Getting a reference to the ViewPager defined the layout file */
ViewPager pager = (ViewPager) findViewById(R.id.pager);
/** Getting fragment manager */
FragmentManager fm = getSupportFragmentManager();
/** Instantiating FragmentPagerAdapter */
Fragment_Pager pagerAdapter = new Fragment_Pager(fm);
/** Setting the pagerAdapter to the pager object */
pager.setAdapter(pagerAdapter);
}
}
But my problem is that i can't figure out how to add fragments to the code. I want to swipe to the next activity with buttons and stuff on them. How do I do that ?
PageAdapter uses your getItem() to switch between Fragments, this is where you would declare which page does what. "Position" 0 is the first page, 1 is the second and so forth. You can simply return a new instance of your other Fragments or pass arguments if you wish.
For example:
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
// Your current main fragment showing how to send arguments to fragment
Fragment_control myFragment = new Fragment_control();
Bundle data = new Bundle();
data.putInt("current_page", position+1);
myFragment.setArguments(data);
return myFragment;
case 1:
// Calling a Fragment without sending arguments
return new MySecondFragment();
case 2:
return new MyThirdFragment();
default:
return null;
}
}
Then you would create a Fragment class for each of those you want to incorporate. In my example you would have a class for MySecondFragment and MyThirdFragment
public class MySecondFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.second_fragment, null);
return view;
}
}
And
public class MyThirdFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.third_fragment, null);
return view;
}
}
Any fragment may simply inflate a standard xml layout file, to access the children in the layout you would have to remember to use the following, I'll use MySecondFragment as an example.
Let's say you have two Buttons with id's R.id.button1 and R.id.button2 in a layout file titled 'second_fragment':
public class MySecondFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.second_fragment, null);
// Make sure to add the parent inflater before and layout child call
Button btn_one = (Button)view.findViewById(R.id.button1);
Button btn_two = (Button)view.findViewById(R.id.button2);
return view;
}
}
Edit
To start at a page other then 0 or the first position you would simply use setCurrentItem() in your MainAvticity, like so:
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(tag, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
FragmentManager fm = getSupportFragmentManager();
Fragment_Pager pagerAdapter = new Fragment_Pager(fm);
// Here you would declare which page to visit on creation
pager.setAdapter(pagerAdapter);
pager.setCurrentItem(1);
}
I have added this in fragment class ..
the issue i got is cannot resolve cannot resolve get support fragment manager ().
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(tag, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
FragmentManager fm = getSupportFragmentManager();
Fragment_Pager pagerAdapter = new Fragment_Pager(fm);
// Here you would declare which page to visit on creation
pager.setAdapter(pagerAdapter);
pager.setCurrentItem(1);
}