75

In the Activity I have :

public class tabsmain extends Activity{
    public static Context appContext;

    public boolean lf_ch=false;

    public void onCreate(Bundle savedInstanceState){

I would like to access and possibly change lf_ch from a fragment inside tabsmain;

public class tabquests extends Fragment{ 
    public CheckBox lc;
@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)//onCreateView
    { 
lc.setChecked(//set it to lf_ch);

However, I can't seem to access the value of lf_ch.

Syntax_Error
  • 5,964
  • 15
  • 53
  • 73
  • 3
    my 2 cents: static Context field is bad, mkay ... and name convetion ... try to not use only small letters in class names 'tabsmain' => 'TabsMain' ... it ok to name var (like: `TabsMain tabsmain = null;`) but when you wana use this class like in David M answer it's hard to know if tabsmain is class name or var ... look t Android SDK classes, java classes they always use first upper – Selvin Oct 25 '12 at 11:10
  • 2
    I hope you've been to one or two variable naming conventions since you posted this :) – Ojonugwa Jude Ochalifu Dec 14 '16 at 10:32
  • I agree with Selvin. Java world is very particular about naming convention. Please see https://www.javatpoint.com/java-naming-conventions. Thanks for the answer. – Dojo Oct 11 '18 at 10:17

14 Answers14

67

Try this:

public View onCreateView(...){
  tabsmain xxx = (tabsmain)getActivity();
  lc.setChecked(xxx.lf_ch);
}
Selvin
  • 6,598
  • 3
  • 37
  • 43
David M
  • 2,511
  • 1
  • 15
  • 18
  • this will only help in reading the variables for the object xxx. However, if I want to read the same variables in the other fragment it wont work. – Syntax_Error Oct 25 '12 at 13:34
  • i could change it as well. improvement : you can you directly as tabsmain.lf_ch you can change as tabsmain.lf_ch=new_value – Arjun Bora Jul 08 '14 at 16:02
33

I know this is an old question, however here is an easier answer that work without jumping through any hoops. In your Fragment, define a variable that would reference the parent Activity. Then in the Fragment's onCreateView, connect the variable to the Activity and then you have a reference that you can use to get any public variable in the MainActivity. I had forgotten it when I ended up here. It's a little hard to do the other way as you need to find the exact fragment that is showing. However with this you shouldn't need to do it the other way, because you can easily pass things back and forth. I hope this help anyone that comes across it.

public Quiz_Avtivity mainQuiz;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_quiz, container, false);

mainQuiz = (Quiz_Avtivity) getActivity();
//Below is where you get a variable from the main activity
mainQuiz.AnyPublicVariable = whatEver;
//also
whatEver = mainQuiz.AnyPublicVariable
rminaj
  • 560
  • 6
  • 28
Mark Dail
  • 501
  • 4
  • 10
  • No problem. Glad to help. If it wasn't for the help I've gotten here I never would have finished any projects. Just thought I would give back since I could. – Mark Dail Mar 23 '16 at 15:02
  • 3
    ...so true! :D ...Thumbs up to stackoverflow team and every one who take the time to give back to the community! :D – S bruce Mar 23 '16 at 21:39
  • 1
    I've been using the same method and it seems to work fine. But as I see a lot of recommendations to use an interface between activity & fragments, I've been wondering if this is really "okay" to do, knowing that my fragments are really meant to only be used with that one activity. – Aba Sep 26 '17 at 01:35
  • 2
    I've had an app in the app store that uses this method. The app has been there for a year now and I have seen no failures that have been caused by doing it this way. As with yours my fragments are used with one activity. I guess if you wanted to use a fragment with more than one activity or visa versa using an interface would be the way to go, in fact to do it this way you have to know exactly what activity the fragment is in. If you tried to use this method putting a fragment into with more than one activity it wouldn't work. – Mark Dail Sep 28 '17 at 15:06
32

if you are using Java, you can use

((YourActivityName)getActivity()).variableName

to access, and if you are using Kotlin, you can use

(activity as YourActivityName).variableName

If the variable is defined as null in kotlin, you have to try each of these method as well:-

(activity as? YourActivityName).variableName

(activity as? YourActivityName)!!.variableName

or have to use let block, if possible.

Choose the correct one for you!

Hope, It will help.

Shubham
  • 535
  • 5
  • 11
7

Make a generic Result receiver

enter image description here

You can create an interface for this task which would fetch a String data from any Activity to your Fragment. Follow these steps.

Create an interface

public interface MyResultReceiver{

      public String getResult();     

} 

Make MyResultReceiver a member of your Fragment

public class tabquests extends Fragment{ 

    public CheckBox lc;
    public MyResultReceiver resultreceiver;

    @Override
    public void onAttach(Context context){
         super.onAttach(cotext);
         resultreceiver = (MyResultReceiver)context;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)//onCreateView
    { 

           YourFragment code code

           Boolean result = resultreceiver.getResult();
           lc.setChecked(result);

     }

}

Implement MyResultReceiver in the Activity and override the method

public class tabsmain extends Activity implements MyResultReceiver{

        public boolean lf_ch=false;

        // Activity code


        @Override
        public boolean getResult(){
             return lf_ch;
        }

 }

Disclaimer:

You might find it a bit lengthy for this case. But the plus point of this approach is that if you want to reuse this code for another activity. You will not have to write the same logic again. Just implement the MyResultReceiver in your activity , override the method and your will be good to go.

TIP: To be able to get any kind of data, change the method definition in the interface
from public String getResult(); to public Object getResult();

Rohit Singh
  • 16,950
  • 7
  • 90
  • 88
  • 3
    This is the best and safest approach and should have been the accepted answer. The other answers doesn't follow android guidelines which states "Fragments are meant to be re-usable and having to cast `getActivity` to a specific activity class is a bad practice because it limits it's usage to that activity and will throw NPE of any other". – Giddy Naya Mar 17 '20 at 14:05
  • Excellent response! One question: Doesn't need tabsmain Activity to add "Implements MyResultReceiver" to implement it? because it actually define the getResult() method, but I can't see why says @Override if the interface is not implemented... I just ask because I'm learning Java, and I'm not sure if it is correct what I'm saying. – Fer B. Jun 06 '20 at 13:47
  • 1
    Yes, the activity should implement it. Good catch @FerB. Updated my code – Rohit Singh Jun 06 '20 at 16:31
5

take Activity value in fragment.

((MainActivity) getActivity()).mGoogleApiClient;

Sanjay Goswami
  • 191
  • 2
  • 7
3

Another way to get data from activity is to access activity's intent via:

getActivity.getIntent().getExtras();

and etc.

It can be useful if you starts activity with fragment in xml, and would like to control somehow fragment's onCreate() behavior.

PS: of cause you should firstly put something to intent

Penzzz
  • 2,814
  • 17
  • 23
2

You could try the following method:

lc.setChecked(((yourpackagename)getActivity()).lf_ch);
0

try tabsmain.appContext.lf_ch will give u value of that variable.

Also in that activity set appContext = this

Sumant
  • 2,775
  • 2
  • 22
  • 30
0

try this

public boolean lf_ch=false;
public class tabsmain extends Activity{

    public static Context appContext;
    public void onCreate(Bundle savedInstanceState){
Linus Caldwell
  • 10,908
  • 12
  • 46
  • 58
0

Try Something like this:

    ViewPager mViewPager = (ViewPager) getActivity().findViewById(R.id.m_view_pager);
Ashish Gupta
  • 737
  • 11
  • 18
0

Access Activity variables in fragment to use static keyword like this:

MainActvity.java

public static boolean lf_ch=false;

tabquestsFragment.java

boolean if_value=MainActvity.lf_ch;

I hope it helps you

Android Geek
  • 8,956
  • 2
  • 21
  • 35
0

note that your fragment loads before the activity. so, you have to call the

tabsmain tabsm=(tabsmain) getActivity();

line in onActivityCreated() method

0

Solution : You can try this.

In tabquests Fragment use this,

public class tabquests extends Fragment{ 
    private tabsmain tabsmainActivity;
    public CheckBox lc;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup 
         container,Bundle savedInstanceState)//onCreateView
    { 
        tabsmainActivity = (tabsmain)getActivity; //typecasting 
        //now you can access the variables of tabsmain activity and make 
        //sure you give them public access in the activity`
        tabsmainActivity.lf_ch; //or do whatever operation you want here.
        lc.setChecked(//set it to lf_ch);
    }
hata
  • 11,633
  • 6
  • 46
  • 69
-2

Change: public boolean lf_ch=false; to: public static boolean lf_ch=false; You can access/change the value with: tabsmain.lf_ch

stalker
  • 55
  • 1
  • 2