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
Related
I'm using 2 EditText next to each other, the left one gains focus on the fragment startup, I want to give the right one focus I've tried to call requestFocus() on the right EditText but it's not working
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.sandwich_fragment,container, false);
sandwichNameEditText = view.findViewById(R.id.sandwich_name_edit_text);
sandwichPriceEditText = view.findViewById(R.id.sandwich_price_edit_text);
insertSandwichImageView = view.findViewById(R.id.insert_sandwich_btn);
sandwichListView = view.findViewById(R.id.sandwich_list);
dbHandler = new DBHandler(getContext(),null);
sandwichArrayList = dbHandler.getSandwiches();
final SandwichListAdapter adpater = new SandwichListAdapter(getContext(),
R.layout.sandwich_item, sandwichArrayList);
sandwichListView.setAdapter(adpater);
insertSandwichImageView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if(sandwichNameEditText.getText().toString().equals("") || sandwichPriceEditText.getText().toString().equals("")){
Toast.makeText(getContext(),"No empty strings.", Toast.LENGTH_SHORT).show();
return;
}
Sandwich sandwich = new Sandwich(sandwichNameEditText.getText().toString(),
Double.parseDouble(sandwichPriceEditText.getText().toString()));
dbHandler.addSandwich(sandwich);
adpater.add(sandwich);
sandwichNameEditText.setText("");
sandwichPriceEditText.setText("");
sandwichNameEditText.requestFocus(); // working here
}
});
sandwichNameEditText.requestFocus(); // not working here
return view;
Try to call requestFocus in the onViewCreated method.
The request for focus is something you should do once your View is created.
You can find some insights about the difference between onCreateView and onViewCreated methods for a Fragment here.
That said, you should move your view elements initialisations in the onViewCreated as well, since they're something you want to do after the view is created and not while it's being created. Just leave the inflate logic there, and do the other logic once the View is there.
Whenever I use or implement onClickListner in Fragment, the application crashes. I have tried all the methods like implementing the fragment class using on click in XML but the application crashes all the time. Please help me with this. I don’t even write anything in the onClick override method and still, the application crashes.
Button btn_edit;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView=inflater.inflate(R.layout.multi_frag,container,false);
btn_edit=(Button)rootView.findViewById(R.id.edit);
btn_edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
return inflater.inflate(R.layout.activity_account,container,false);
}
The application is crashing because you are returning a different view and finding the button in a different view.
// In below line you are using R.layout.multi_frag
View rootView=inflater.inflate(R.layout.multi_frag,container,false);
btn_edit=(Button)rootView.findViewById(R.id.edit);
btn_edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
// And here, you are returning R.layout.activity_account.
return inflater.inflate(R.layout.activity_account,container,false);
You cannot use two layouts within one fragment. Check the right layout which contains the button and use that layout in both of the places.
by this answer
I can't understand where to put my onClickListener() - inside onCreateView() or inside onActivityCreated() , below codes describe it better:
CODE A: (Setting Button click listener inside onActivityCreated())
private FloatingActionButton bt;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do something.
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.first_frag, container, false);
bt = (FloatingActionButton) v.findViewById(R.id.fab);
return v;
}
CODE B: (Setting Button click listener inside onCreateView())
private FloatingActionButton bt;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.first_frag, container, false);
bt = (FloatingActionButton) v.findViewById(R.id.fab);
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do something.
}
});
return v;
}
I may have not understood which code is better because of my poor English, anyway, thank you all :)
Both will have no effect as far as I know. Once the view is inflated you can put it anywhere either in onCreateView() or in onActivityCreated().
After all, for binding views and setting click listeners, onViewCreated() is a better candidate though, as it will be called immediately after onCreateView. It clearly suggests that your view has been inflated.
There is no specific reason or rule for it. Google itself doesn't care much about it. As a rule of thumb, you can put it anywhere you want once the view is inflated.
I would suggest putting the onClickListener it inside the onActivityCreated. And binding the button to the view inside onCreateView. Just like you have done the first time in your question.
To read more regarding the methods you can go through this post
Since onActivityCreated was deprecated in API level 28, it's probably wise to put it in onCreateView!
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.
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.