public class Home extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.home,null);
}}
This is the whole code for fragment tab 1..
I have a program with two TabFragments , and I want to declare an image button and button intent in fragment tab 1 and 2, but I can't do it , and the findviewbyid did not work..
What can I do to declare buttons intent ??
To handle button clicks (and view clicks in general) View.OnClickListener interface is used. All you have to do is override its onClick method and assign it to a view by calling setOnClickListener().
You can also find a thorough tutorial here.
UPD: Your method should look like this:
public View onCreateView(.....) {
// assign inflated view to a variable
View v = inflater.inflate(R.layout_services, null);
// set your listener
v.findViewById(R.id.imageButton).setOnClickListener(.....);
// return the view in the end
return v;
}
The problem is that you're instantly returning the inflated view and the code below wouldn't run at all, this is why there's that error.
UPD2: Now the problem is that startActivity method is receiving Context as a first parameter, so you should pass your activity there by calling getActivity() (instead of passing Services.this). You can read more here.
UPD3: You don't seem to understand what your code does. Your findViewById call is useless because it's not getting assigned to a variable, and your setOnClickListener is getting applied to the entire fragment view. Here's what that part should look like:
ImageButton button = (ImageButton) v.findViewById(R.id.imageButton);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Activity activity = getActivity();
Intent intent = new Intent(activity, Admin.class);
activity.startActivity(intent);
}
});
I'd recommend to learn how all those methods work (at least have a look at the reference, to begin with: here and here) before trying to actually write an application. Good luck with it.
Related
Since, i am new to android, i am trying to learn fragments and how they work.I tried to make a length converter app which basically converts meter to centimeters.Simple, right?
Now I have two portions of the activity,one being the two edittexts which are the part of the activity layout, while the other one being the fragment.
This fragment basically contains keypad, in short, Numbers and operators displayed on it. Like a normal calci would have.
Now i read about the fragment life cycle and how it is supposed to work.
So The first thing that i did was to put everything in onCreateView method.
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
getRootView=inflater.inflate(R.layout.calci_keyboard,container,false);
GridLayout gridLayout=(GridLayout) getRootView.findViewById(R.id.calciKeyboardGrid);
for(int i=0;i<gridLayout.getChildCount();i++){
b=(Button)gridLayout.getChildAt(i);
b.setBackground(getResources().getDrawable(R.drawable.button_dark_gradient));
b.setOnClickListener(this);
}
return getRootView;
}
The thing is that, click events work but edittext settext doesn't seem to work. Edittexts are behaving weirdly.
Now, to remove that i thought i am accessing the Activity UI's , so i should do this inside onActivityCreated function ,So, i tried this too.
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
getRootView=inflater.inflate(R.layout.calci_keyboard,container,false);
return getRootView;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
#SuppressLint("InflateParams") View getView=(GridLayout) LayoutInflater.from(getActivity()).inflate(R.layout.calci_keyboard,null,false);
GridLayout gridLayout=(GridLayout) getView.findViewById(R.id.calciKeyboardGrid); // i Logged this obj and it was there
for(int i=0;i<gridLayout.getChildCount();i++){
b=(Button)gridLayout.getChildAt(i);
b.setBackground(getResources().getDrawable(R.drawable.button_dark_gradient));
b.setOnClickListener(this);
}
}
When i do things this way i don't seem to get my clicks working?
How am i supposed to do this problem? Can't find any solution.
Go easy on me,Thanks :)
Below one shows my onClick event:.
public void onClick(View view) {
View focussedChild=getActivity().getCurrentFocus();
switch (view.getId()){
case R.id.calciKeyboardNine:{
if (focussedChild instanceof EditText) {
firstPart=new StringBuilder("");
secondPart=new StringBuilder("");
EditText editText=(EditText)focussedChild;
if(focussedChild.getId()==R.id.lengthConverterFirst){
if(!TextUtils.isEmpty(firstPart.toString()))
firstPart.replace(0,firstPart.length()-1,editText.getText().toString()+"9");
firstPart.append("9");
editText.setText(firstPart.toString());
editText.setSelection(editText.length());
int a=Integer.parseInt(firstPart.toString());
a=a*100;
editText=getActivity().findViewById(R.id.lengthConverterSecond);//second edit text
editText.setText(Integer.toString(a));
editText.setSelection(editText.length());
}else if(focussedChild.getId()==R.id.lengthConverterSecond){
if(!TextUtils.isEmpty(secondPart.toString()))
secondPart.replace(0,secondPart.length()-1,editText.getText().toString()+"9");
secondPart.append("9");
editText.setText(secondPart.toString());
editText.setSelection(editText.length());
double a=Integer.parseInt(firstPart.toString());
a=a/100;
editText=getActivity().findViewById(R.id.lengthConverterFirst);//first edit text
editText.setText(Double.toString(a));
editText.setSelection(editText.length());
}
}
}
}
}
Now, to remove that i thought i am accessing the Activity UI's , so i should do this inside onActivityCreated function ,So, i tried this too - it didn't work because onActivityCreated() is method of fragment not activity.
try this - just make your edittexts static in activity and then you can access them in fragment by the activity's name like MainActivity.editText(). hope this helps
I am using the android studio fragments sample. My goal is to set the value of EditText et1 in fragment1 by using code in fragment2. Also I want to update the ListView lv, that is in fragment1 by using code in fragment2.
The example does some back and forth sending of ARG_SECTION_NUMBER, but that is just text and won't work for a listview. What does not work is this
private View rvza, rvl, rvea;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rvza = inflater.inflate(R.layout.fragment_zeit_und_aktion, container, false);
rvl = inflater.inflate(R.layout.fragment_liste, container, false);
rvea = inflater.inflate(R.layout.fragment_eintragen_und_aendern, container, false);
....
}
...
Button btnNeu = (Button) rvea.findViewById(R.id.btnNeu); //this line is somewhere...
What also doesn't work is this
new MainActivity().myfunction((ListView)rvl.findViewById(R.id.listView));
it gives an Attempt to invoke interface method 'int
android.widget.ListAdapter.getCount()' on a null object reference at
public void myfunction(ListView lv)
{
int count = lv.getAdapter().getCount();
So how do I communicate between fragments having one parent activity? Is there a helper class?
If you want to access any method or variable, that has an use by more than one child, make parent activity singleton and access the desired method or variable in child fragment. Also if you want to access anything within fragment from anther, don't forgot to make and init an object of that fragment in parent activity and use that object further to add or replace fragment in fragment manager. By this you have access to every child through the parent activity
How to make singleton? See below example.
public class SingletonExample {
// Static member holds only one instance of the
// SingletonExample class
private static SingletonExample singletonInstance;
// SingletonExample prevents any other class from instantiating
private SingletonExample() {
}
// Providing Global point of access
public static SingletonExample getSingletonInstance() {
if (null == singletonInstance) {
singletonInstance = new SingletonExample();
}
return singletonInstance;
}
public void printSingleton(){
System.out.println("Inside print Singleton");
}
}
There is an official guide on Android developers on how to communicate between fragments:
https://developer.android.com/training/basics/fragments/communicating.html
Basically, your fragment A will talk to the activity via an interface and the activity will look up fragment B and call some method on the fragment.
If you want to decouple things more, however, you could use something like otto event bus:
http://square.github.io/otto/
It can be used to communicate between different parts of your application without having to deal with the underlying details.
The problem is MainActivity starts with a setContentView with a layout.xml. We can add buttons or anything to the layout and code in in the MainActivity class but when I try to code the buttons of another layout in the same Activity the app forces stop . Whats wrong ?
Ok I found out that is because of the context.
When you try to change other activity you have to use layoutinflater. Example below
LayoutInflater inflater = getLayoutInflater();
View myLayout = inflater.inflate(R.layout.my_layout, null);
To work with widgets inside it like buttons or anything .
Button b = mylayout.findViewById(R.id.button);
b.setText("Successfully changed");
Now you can use myLayout as your changed layout.
Please sent me your Activities
What the text of problem ?
You may write next code to go to another activity
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(),nameActivity.class));
}
});
Where button is name of your button
See that you xml-file doesnt have any mistakes
You are getting a crash because you are trying to access the layout when it is not inflated. In other words, you must call setContentView() on an Activity, or inflater.inflate() on a Fragment to instantiate the view and make the elements accessible for manipulation. So if you want to add buttons to another Activity, you would need to call its onCreate() and setContentView() before you can add buttons to it.
EDIT: In response to comments...
In order to access/manipulate/modify elements in a layout at runtime, they must first be instantiated, which happens when the view is inflated. So to add a button to an Activity at runtime, you would do it in the onCreate() method after calling setContentView() like this:
Keep in mind this is the onCreate() of your SECOND activity...not your main Activity. So your main activity would start this Activity, then the button would get created during the setup of the second Activity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_second_activity;
Button button = new Button(this);
button.setText("Your New Button");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("NEW BUTTON", "I just clicked my new button!");
}
});
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.layout_in_your_second_activity);
relativeLayout.addView(button);
}
If you are using a Fragment to display your UI, you can't access your UI elements until you have inflated your layout, which happens in the onCreateView() method. So you would do something like this in your Fragment code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.your_fragment_layout, container, false);
RelativeLayout relativeLayout = (RelativeLayout) view.findViewById(R.id.container_layout_that_holds_button);
//You would get your context from an onAttach() Override
Button button = new Button(context);
button.setText("Your New Button");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("NEW BUTTON", "I just clicked my new button!");
}
});
relativeLayout.addView(button);
return view;
}
You're likely getting a NullPointerException when you try to manipulate your layouts before they are created. Keep in mind that even if you have an XML file with layouts specified within, the actual objects for those elements won't be created until the system decides it needs them, which happens when you actually try to display the view.
This is more of a design question and how one would go about designing applications. I have been having fun with fragments, but one thing that doesn't make sense to me something like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("someInt", 2);
Button btnOne = (Button) getView().findViewById(R.id.one);
btnOne.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
String currentText = getScreen().getText().toString();
currentText += "1";
getScreen().setText(currentText);
}
});
}
// Inflate the view for the fragment based on layout XML
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.standard_calculator, container, false);
return view;
}
/** Return the screen TextView object for manipulation
* #return screen
*/
public TextView getScreen() {
return screen;
}
Screen title are private variables in the class and this isn't the whole class, but just the part that I need to help my question. There are going to be at least 15 or so buttons that manipulate the screen and it doesn't feel like good practice to and put them all in the onCreate method, I was wondering whether it would be better design to have them in another class that let the methods in the fragment be more specific to the life-cycle of the fragment, although one can say that the buttons are used by the fragment and therefore should be part of the class. Perhaps an "initialising" method is needed.
I was hoping someone might be able to direct me to some design patterns or logical way of thinking about application design, it is quite different.
Many thanks.
Putting them in the XML is less versatile than doing it in code. If you don't want to have XXX anonymous methods, you can make your own Fragment/Class implement View.onClickListener and implement the onClick method:
#Override
public void onClick(final View v) {
if ( v.getId() == R.id.btn_logout ){
// Do One Thing
} else if ( v.getId() == R.id.btn_about) {
// Do Something Else
} else if ( v.getId() == R.id.btn_shutdown) {
// Or Maybe do this :)
}
}
Then in your onViewCreated just assign each button with "this"
final someBtn = (Button) view.findViewById(R.id.btn_logout);
someBtn.setOnClickListener(this);
That can be cleaner looking than a bunch of anonymous methods and you know you have your click listeners in one place.
You don't have to initialize them all in the onCreate() method. In fact, you don't have to initialize them in java code at all. You could simply define them in xml and define an "onClick" property in your xml. The method that you set in "onClick" will be called for that button. It's one way to make your Activities cleaner.
I have a normal class (not an activity). Inside that class, I have a reference to an activity.
Now I want to access a view (to add a child) contained in the layout xml of that activity.
I don't know the name of the layout file of that activity. I only know the ID of the view, which I want to access (for example: R.id.my_view).
How can I do that?
Regarding the NullPointerException (which you should add to the question), always make sure you've called setContentView() in your Activity before trying to access a View defined in XML. Example usage:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
}
...
}
Then, somewhere,
ViewGroup group = (ViewGroup) context.findViewById(R.id.group); // In your example, R.id.my_view
The reason you need to have called setContentView() is that before it's called, your View(Group) doesn't exist. Because findViewById() is unable to find something that doesn't exist, it returns null.
As simple as that!
View view = activity.findViewById(R.id.my_view);
In case of the Layout:
LinearLayout layout = (LinearLayout) activity.findViewById(R.id.my_layoutId);
And to add the Views:
layout.addView(view);
You could make your method accept an Activity parameter and then use it to find the view by id.
Ex:
public class MyClass{
public void doSomething(Activity context){
TextView text=(TextView)context.findViewById(R.id.my_textview);
}
}
Then in your activity:
obj.doSomething(YourActivity.this);