I want to use custom dialog in my Android app so I create a class that extends DialogFragment and I use it in a Fragment class however it's not working.
There is my custom dialog class:
public class MyDialogue extends DialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return inflater.inflate(R.layout.my_dialog, null);
}
}
//my_dialog.xml has the layout of dialog
enterData(View view) method is set onClick property of a button in espensecashfragment.xml
There is my fragment from which my dialog should be shown :
//This is where I want to use the dialog
public class ExpenseCashFragment extends Fragment implements AdapterView.OnItemSelectedListener {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.expensecashfragment, container, false);
return view;
}
public void enterData(View view){
FragmentManager manager = getFragmentManager();
MyDialogue myDialogue = new MyDialogue();
myDialogue.show(manager, "MyDialogue");
}
}
There is part of espensecashfragment.xml, button linked to enterData method :
<Button
android:id="#+id/enterButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/relativeLayout"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Enter"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:layout_marginBottom ="100dp"
android:onClick="enterData" />
Related
I know that to show a list of views I can use recycler view with but what if I wanna reuse also my fragment logic too?
for example, if I have a fragment like this
XML
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".views.fragments.testview">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="hi"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Fragment class
public class TestView extends Fragment {
private TextView txt;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.test, container, false);
initComponent(v);
return v;
}
private void hardTask1(){};
private void hardTask2(){};
//Some other hardtask
}
What I could do if I need to display a list of fragments in some activity but I don't want to rewrite all my TestView in the adapter?
public class Menu1 extends Fragment implements View.OnClickListener {
public static Button button_sbm;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
//returning our layout file
//change R.layout.yourlayoutfilename for each of your fragments
/* return inflater.inflate(R.layout.fragment_menu_1, container, false);*/
View myView = inflater.inflate(R.layout.fragment_menu_1, container, false);
button_sbm = (Button) myView.findViewById(R.id.button);
button_sbm.setOnClickListener(this);
return myView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//you can set the title for your toolbar here for different fragments different titles
getActivity().setTitle("Home");
}
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), MainWeb.class);
startActivity(intent);
}
}
How To Intent To MainWeb Class..
This My XML
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/yoga"
android:layout_alignParentTop="true" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:text="Goto Website"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
Fragment to Activity
What to do?
When I click the button, it gives me a message
"Unfortantly App Was Stopped"
Make sure your MainWeb Activity class is mentioned in AndroidManifest.xml.
Don't create a static instances of Button or any UI widget in your fragment or Activity. That may lead to memory leak.
I am new to the android platform so I know I am just missing something by here is what I have
<!-- activity_main -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.example_app.MainActivity"
tools:ignore="MergeRootFrame" >
<fragment
android:id="#+id/mainFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.example_app.MainFragment"
/>
</FrameLayout>
Then I created a fragment called MainFragment.java.
public class MainFragment extends Fragment {
public TextView displayTextView;
public MainFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
this.displayTextView = (TextView)rootView.findViewById(R.id.displayTextView);
return rootView;
}
}
I add the fragment in the OnCreate function in the activity and it seems to be adding everything okay but when I click on the button nothing happens, I logged the function to see its being called but setting the textview doesn't do anything. What am I doing wrong?
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.example_app.MainActivity$PlaceholderFragment" >
<Button
android:id="#+id/button10"
android:textColor="#ffffff"
android:textSize="34dp"
android:text="10%"
android:layout_below="#id/amountEditText"
android:background="#drawable/pct_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doSomething"
/>
<TextView
android:text="Blah Blah Blah"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/displayTextView"
></TextView>
</RelativeLayout>
And here is the click Event in the MainActivity.java
public void doSomething(View v) {
this.mainFragment.displayTextView.setText("Nothing to set for some reason!");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
//
this.mainFragment = (MainFragment) getSupportFragmentManager().findFragmentById(R.id.mainFragment);
mainFragment = new MainFragment();
getSupportFragmentManager().beginTransaction().add(mainFragment, "mainFragment").commit();
}
}
Declaring onClick-Listeners via XML is possible if you work with Activities. According to the Google API, however, you need to declare OnClickListeners programmatically if you use Fragments.
[...] You can also declare the click event handler programmatically rather than in an XML layout. This might be necessary if you instantiate the Button at runtime or you need to declare the click behavior in a Fragment subclass.
Source:
http://developer.android.com/guide/topics/ui/controls/button.html
So you may want to use this instead:
public class MainFragment extends Fragment {
public TextView displayTextView;
public Button yourButton;
public MainFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
this.displayTextView = (TextView)rootView.findViewById(R.id.displayTextView);
yourButton = (Button)rootView.findViewById(R.id.button10);
yourButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
displayTextView.setText("Nothing to set for some reason!");
}
});
return rootView;
}
}
The problem is the way you try to execute the button click. From your question i understand that Button and TextView is in Fragment view. So do why are Trying to access it in activity ?? It is wrong, then there is no point of using Fragments. Also this will lead to many serious issues later .
Fragments are Reusable components so all the functionalities of a fragment must stay inside the Fragment Class
Change Fragment code :
public class MainFragment extends Fragment {
public TextView displayTextView;
public Button yourButton;
public MainFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
this.displayTextView = (TextView)rootView.findViewById(R.id.displayTextView);
yourButton = (Button)rootView.findViewById(R.id.button10);
//Setting click listener for button in fragment
yourButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
displayTextView.setText("Nothing to set for some reason!");
}
});
return rootView;
}
}
and remove android:onClick="doSomething" from XML
I have an xml file as shown below:
One.xml
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="#drawable/additemsbackground"
android:orientation="horizontal"
android:layout_marginRight="20dp"
android:layout_marginLeft="20dp">
<ImageView
android:id="#+id/btnaddtxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:layout_marginRight="10dp"
android:adjustViewBounds="true"
android:src="#drawable/add" />
</LinearLayout>
This is my MainFragment:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LayoutInflater layoutInflater = LayoutInflater.from(MainActivity.this);
View myView = layoutInflater.inflate(R.layout.One,
null);
ImageView btnadd=(ImageView)myView.findViewById(R.id.btnaddtxt);
btnadd.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(),
"Clicked Add Text Button" , Toast.LENGTH_LONG)
.show();
}
});
}
When I'm trying to get the ImageView as shown in my MainFragment it always returns null.
Can anyone say me what's the correct way of doing this ?
Initialize your views in onCreateView(...) and not in onCreate(...) when using Fragments. Something like this
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.delivery_boys, container,
false);
ImageView btnadd=(ImageView)rootView .findViewById(R.id.btnaddtxt);
return rootView;
}
you are suppose to inflate view in onCreateView in your fragment class
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.delivery_boys, container,
false);
ImageView img=(ImageView)view.findViewById(R.id.your_img_view);
return view;
}
onCreateView function you get attached to the activity and you get you get view inflation opportunity in onCreate Method Fragment is initialized and not yet attached to activity.
#Override
public View setContentView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mChangeVehiclesView == null) {
mChangeVehiclesView = inflater.inflate(
R.layout.frag_vehicles_registered, null);
} else {
((ViewGroup) mChangeVehiclesView.getParent())
.removeView(mChangeVehiclesView);
}
mvehicleListView = (ListView) mChangeVehiclesView
.findViewById(R.id.frag_vehicle_registeres_list);
return mChangeVehiclesView;
}
The following is running on an Android 1.6 so I'm using the compatibility package for fragments. In the following TestFragment is a static nested class:
public class FragmentTestActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public static class TestFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView result = new TextView(getActivity());
result.setText("Hello TestFragment");
return result;
}
}
}
The main.xml file:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<fragment class="com.test.FragmentTestActivity$TestFragment"
android:id="#+id/test"
android:layout_width="fill_parent" android:layout_height="fill_parent" />
</FrameLayout>
The strange thing is that the container parameter in onCreateView is null.
Now, if I add the fragment programatically like so(just change the onCreate method of the Activity) the container is no longer null. Why?
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fragment frag = new TestFragment();
getSupportFragmentManager().beginTransaction().add(android.R.id.content, frag).commit();
}
The documentation mentions that it can be null:
public View
onCreateView(LayoutInflater
inflater, ViewGroup container, Bundle savedInstanceState)
[...]
container: If non-null, this is the parent view that the
fragment's UI should be attached to. The fragment should not add the
view itself, but this can be used to generate the LayoutParams of the
view.
To be clear: you shouldn't do anything like container.addView(...).