i am creating two java file 1st main activity.java file 2nd fragment.java file create button on fragment.java how to click listener written on activity.java help me
fragment.java
public class fragment extends fragment{
Button btn;
// some code
btn = (Button)layout.findviewbyid(R.id.btn1);
}
}
activity.java
public class activity extends Activity
{
// how to access the click action btn here
btn.setOnclicklistner(new View.OnClickLisitner(){
public OnClick(){
}
To use the button in activity from the fragment, you have to use getActivity()
In your fragment,
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_item_select, container, false);
btn = (Button) getActivity().findViewById(R.id.btn);
}
btn is the button in activity
getActivity() in a Fragment returns the Activity the Fragment is currently associated with. (see http://developer.android.com/reference/android/app/Fragment.html#getActivity()).
You can define custom clickListener class and create it's instance in fragment and set listener instance there. Now you can write code in that class. Hope it will help you.
public class MyCustomListener implements OnClickListener{
#override
public void onClick(View v){
// you stuff
}
}
then in your fragment call this
MyCustomListener listener=new MyCustomListener();
btn.setOnClickListener(listener);
Here is my take on the issue, both in Java and Kotlin.
Java:
public final class YourActivity extends AppCompatActivity {
/***/
public final void yourMethod() {
printIn("Printing from yourMethod!")
}
}
public final class YourFragment extends Fragment {
/***/
#Override
public void onViewCreated(View v, Bundle savedInstanceState) {
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
YourActivity yourActivity = (YourActivity) getActivity();
yourActivity.yourMethod();
}
}));
}
}
Kotlin:
class YourActivity : AppCompatActivity() {
/***/
fun yourMethod() {
print("Printing from yourMethod!")
}
}
class YourFragment: Fragment() {
/***/
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
button.setOnClickListener {
val yourActivity = activity as YourActivity
yourActivity.yourMethod()
}
}
}
I hope it helps someone out there =)
If I understand your problem correctly, you want to delegate a button click inside a fragment back to its parent activity.
Keep a reference to the parent activity inside your fragment. Then set the listener to your button in your fragment like this:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
parentActivity.doStuff();
}
};
In your parent Activity, define method doStuff():
public void doStuff() {
// handle button click event here
}
Related
I have a listview in my tablayout. When I click on one of these elements, I want that element to be added to a list in the mainactivity. So that I can display this list on another fragment.
You can use interface when clicked on item
Create interface like this in one fragment
public interface OnClickListener{
void onClick(Item listItem);
}
and in fragment create object like:
OnClickListener onClickListener;
and in onAttach assign the object
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
onClickListener= (onClickListener) context;
} catch (ClassCastException e) {
}
}
and then implement this listener in your MainActivity
public class MainActivity extends AppCompatActivity implements onClickListener{}
and on button click in fragment pass the data to your MainActivity
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
onClickListener.onClick(YOUR_ITEM);
}
});
The application has a BottomNavigationView for navigating between fragments. One of the Fragments related to the BottomNavigationView has a Fragment as a child containing a RecyclerView and each RecyclerView Item has a Button attached to it.
I would need to navigate the BottomNavigationView to another Fragment with an OnClick of the Button (Highlighted with the red) inside the RecyclerView Item. I have tried different ways but I have not gotten it to work so far.
The Click is handled inside the Adapter of the RecyclerView. (The code inside the OnClickListener is just to clarify what I am trying to do.)
#Override
public void onBindViewHolder(#NonNull LocationsViewHolder holder, int position) {
...
holder.showMarkerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
BottomNavigationView navigation = (BottomNavigationView)v.findViewById(R.id.nav_view);
navigation.setSelectedItemId(R.id.navigation_map);
}
});
}
The easiest way is created an interface implemented by your Activity
First create an interface that i called OnItemClick :
public interface OnItemClick{
void onItemClick();
}
Following on your activity implement this interface like below :
public class MainActivity extends AppCompatActivity implements OnItemClick{
/*
rest of your code
*/
#Override
public void onItemClick() {
navigation.setSelectedItemId(R.id.navigation_map);
}
}
On your Fragment you need to pass the Activity into your Adapter
YourAdapter adapter = new YourAdapter(requireActivity());
And on your adapter you need to initialize the interface like below :
OnItemClick listener;
public YourAdapter(Activity activity) {
listener= ((MainActivity) activity);
}
And finaly to call the method on your activity just call it like below
#Override
public void onBindViewHolder(#NonNull LocationsViewHolder holder, int position) {
...
holder.showMarkerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick();
}
});
}
New to kotlin/android so excuse my beginner skills.
However, why is View being passed in onClick(v: View) where the type should usually be? (e.g Int, String) etc.
I didn't think this was possible/allowed.
My code:
class MainActivity : AppCompatActivity(), View.OnClickListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
choose_1_player.setOnClickListener(this)
}
override fun onClick(v: View) {
when (v.id){
R.id.choose_1_player -> println("Hello")
R.id.choose_2_player -> println("Hello")
}
}
}
Is it because the function is written in Java and not Kotlin?
Because
1.We click on a View it may be a Button , TextView ,EditText or any layout so on the basis of Integer ID difficult to match with actual views.
2.View has many information including its Id ,that can be used like (Tag , Text etc).
3.Also view has its parent Layout Information can be used .
Please find more details at below link:
Why do we have to add 'View' as parameter in onClick method and what it does?
View class has interface with method onClick(View view).
/**
* Interface definition for a callback to be invoked when a view is clicked.
*/
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* #param v The view that was clicked.
*/
void onClick(View v);
}
MainActivity class is implementing View.OnClickListener interface, which has the following signature:
public interface OnClickListener {
void onClick(View v);
}
So onClick method is implemeted and it receives View as the parameter.
v - is a view which was clicked.
Addition:
The syntax of the overridden onClick method in Kotlin is the following:
override fun onClick(v: View) { ... }
where v - is a view which was clicked; View - is the data type of object v from Android SDK. It is a parent class for many children, such as Button, TextView etc. That means onClick method can receive a Button, TextView, ImageView and other views that inherit from View. Here works one of the principles of OOP - Polymorphism.
The View attribute inform which View you clicked (every visual component of Android is a View) so you can use this information to identify "who" is calling the onClick.
If in my layout I have 3 buttons (button1, button2, button3) I can do something like this (in Java):
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
button1 = findViewById(R.id.button1);
button2 = findViewById(R.id.button2);
button3 = findViewById(R.id.button3);
button1.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch(view.id) {
case R.id.button1:
button1Action();
break;
case R.id.button2:
button2Action();
break;
case R.id.button3:
button3Action();
break;
}
}
Or you can do something like this and ignore the View attribute
public class MainActivity extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
button1 = findViewById(R.id.button1);
button2 = findViewById(R.id.button2);
button3 = findViewById(R.id.button3);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
button1Action();
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
button2Action();
}
});
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
button3Action();
}
});
}
PS.: I didn't run this code. Probably it has some errors.
I have a main Activity in which I created a ViewPager that instantiate 3 other Fragments. One of these is a GridView which makes a popup appear when the user click on one item. Then, in this popup, I have a simple button.
What I want to do is: when the user click on this button, I would like to access a method in my main Activity (that should change the current item of my ViewPager) and then dismiss the popup.
I tried everything I could, but I cannot achieve this... I can set up the click event on my popup and dismiss it easily, but I didn't find out how I can access a method (or even a variable) from my popup to my main Activity.
I will put my most relevant code in here so you can understand the structure of my classes (hopefully...).
My main Activity:
public class MainActivity extends FirstActivity{
private ViewPager mViewPager;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
// Set an Adapter on the ViewPager
mViewPager.setAdapter(new MainActivity_Adapter(getSupportFragmentManager()));
public void onSaveInstanceState(Bundle savedInstanceState)
{
menuBar.onSaveInstanceState(savedInstanceState);
}}
My ViewPager activity:
public class MainActivity_Adapter extends FragmentPagerAdapter{
public MainActivity_Adapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int position)
{
// Set the color background for each page
switch (position)
{
case 0:
return MainActivity_Inventory.newInstance();
case 1:
return MainActivity_Map.newInstance();
default:
return MainActivity_AR.newInstance();
}
}
// The number of Splash Screens to display
#Override
public int getCount()
{
return 3;
}}
My "Inventory" Fragment
public class MainActivity_Inventory extends Fragment implements View.OnClickListener{
public static MainActivity_Inventory newInstance()
{
MainActivity_Inventory frag = new MainActivity_Inventory();
Bundle b = new Bundle();
frag.setArguments(b);
return frag;
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Select the layout
int layout;
layout = R.layout.activity_inventory_01;
// Inflate the layout resource file
View view = getActivity().getLayoutInflater().inflate(layout, container, false);
// Set the grid view
GridView gridview = (GridView) view.findViewById(R.id.inventory_gridView);
gridview.setAdapter(new InventoryImageAdapter(super.getActivity()));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
public void onItemClick(AdapterView parent, View v, int position, long id)
{
// Create a popup to show item details
createPopup();
}
});
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
}
public void createPopup()
{
DialogFragment newFragment = new PopupActivity_Inventory();
newFragment.show(getFragmentManager(), "itemDetails");
}
#Override
public void onClick(View v)
{
}}
And my popup dialog fragment:
public class PopupActivity_Inventory extends DialogFragment{
#Override
public Dialog onCreateDialog(final Bundle savedInstanceState)
{
// Build the alert dialog
final Dialog dialog = new Dialog(this.getActivity());
// Get the layout inflater
final LayoutInflater inflater = getActivity().getLayoutInflater();
// Set up the dialog box
dialog.setContentView(inflater.inflate(R.layout.activity_inventory_popup_01, null));
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.getWindow().setGravity(Gravity.TOP);
//dialog.getWindow().getAttributes().y = 100;
(dialog.findViewById(R.id.brick_button_01)).setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
// When button is clicked, ACCESS MAIN ACTIVITY!
dialog.dismiss();
}
});
return dialog;
}}
I really hope you can help me with this... I really need to get it working. Thank you very much!
If you need further details or explanation, please just tell me.
The best thing to do is use EventBus library. I have a demo app in which you can add items to RecyclerView from anywhere within the app using EventBus. You can use it as a reference to simply do something else instead of current task. Here is the link to the repo:
https://github.com/code-crusher/android-demos/tree/master/EventBusDemo
And if you want to understand how it works you can refer to my article, it explains how to make communications like this easy:
https://medium.com/#code_crusher/eventbus-for-android
Hope it helps. Happy coding :)
Read this https://developer.android.com/training/basics/fragments/communicating.html
Look for "To allow a Fragment to communicate up to its Activity, you can define an interface in the Fragment class and implement it within the Activity...."
Another way to achieve it is using an EventBus and post events by Fragments to be caught by Activities.
Over the past days I've desperately been trying to build an android app with a simple fragment (which I use twice). I want to pass the contents of the fragments' EditText-boxes to a new activity. I just can't figure out how to get those contents from the fragments. What I have so far is this:
I've got my edit_text_fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="#+id/my_edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="my hint" />
</LinearLayout>
and the corresponding MyEditTextFragment.java:
public class MyEditTextFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_text_fragment, container, false);
return view;
}
}
I then use this fragment twice in my main.xml like this:
<LinearLayout 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:orientation="vertical">
<fragment
android:id="#+id/detailfragment_placeholder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
class="com.example.fragmenttester5.MyEditTextFragment" />
<fragment
android:id="#+id/detailfragment_placeholder2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
class="com.example.fragmenttester5.MyEditTextFragment" />
<Button
android:id="#+id/submit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit all of it" />
</LinearLayout>
and in my MainActivity I hooked up the button to a new activity:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button submitButton = (Button) findViewById(R.id.submit_button);
submitButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v){
Intent intent = new Intent(MainActivity.this, OtherActivity.class);
intent.putExtra("result1", "the_result_from_the_first_editText");
intent.putExtra("result2", "the_result_from_the_second_editText");
startActivity(intent);
}
});
}
}
I think I now need to define some kind of interface in the Fragment, but I can't find how. I read a couple examples and tutorials (like this one), but they make no sense to me at all. I don't understand the code given and I just don't understand how to adjust it for my use case.
So my question; can anybody help me to get the contents of the fragment from within the activity? Examples would be very very welcome since I'm just banging my head against the wall here..
You are right, that's kind of a standard way to pass data from a Fragment to an activity.
Basically you define a Listener interface which the Activity implements, and the Activity registers itself as a Listener with the Fragment.
Here's a simple example:
Fragment
class MyFragment extends Fragment {
interface Listener {
public void somethingHappenedInFragment(Object... anyDataYouWantToPassToActivity);
}
private Listener mListener;
public void setListener(Listener listener) {
mListener = listener;
}
// ... your code ...
// Now here you pass the data to the activity
mListener.somethingHappenedInFragment(some, data);
// ... more of your code
}
Activity
public MyActivity extends Activity implements MyFragment.Listener {
// ... your code ...
// creating the Fragment
MyFragment f = new MyFragment();
// register activity as listener
f.setListener(this);
// ... more of your code
// implementation of MyFragment.Listener interface
#Override
public void somethingHappenedInFragment(Object... anyDataYouWantToPassToActivity) {
// here you have the data passed from the fragment.
for (Object o : anyDataYouWantToPassToActivity {
System.out.println(o.toString();
}
}
}
On a high level, there are two tasks that you commonly need to solve with Fragments. The first is communicating data from an Activity to a Fragment. The second is communicating data from a Fragment to an Activity.
An Activity knows which Fragments it contains since it creates them, so it's easy to communicate that way - just call methods on the Fragment itself. But the inverse is not true; Fragments might be attached to any number of random Activities, so it doesn't know anything about it's parent.
The solution is to implement an interface that the Activity implements and the Fragment knows how to communicate with. That way, your Fragment has something it knows how to talk with. There are specific code examples for how to do it here: http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
(In particular, check out the "Creating event callbacks to the activity" code examples).
So you'd create an Interface to talk with the Activity if the event happened in the Fragment. For situations like this, you can simply make an accessible method in the Fragment that the Activity can call. So
public class MyEditTextFragment extends Fragment {
private EditText mEditText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_text_fragment, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mEditText = (EditText) getView().findViewById(R.id.my_edit_text);
}
public Editable getText() {
return mEditText.getText();
}
}
Then
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MyEditTextFragment fragment1 = (MyEditTextFragment)
getFragmentManager().findFragmentById(R.id.detailfragment_placeholder);
final MyEditTextFragment fragment2 = (MyEditTextFragment)
getFragmentManager().findFragmentById(R.id.detailfragment_placeholder2);
Button submitButton = (Button) findViewById(R.id.submit_button);
submitButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v){
String firstResult = fragment1.getText().toString();
String secondResult = fragment2.getText().toString();
Intent intent = new Intent(MainActivity.this, OtherActivity.class);
intent.putExtra("result1", firstResult);
intent.putExtra("result2", secondResult);
startActivity(intent);
}
});
}
}
This assumes that you assigned the Fragment tags in your FragmentTransaction. Be sure to check for null Fragments (omitted for brevity)
Activity will be received data from updateDetail() method in Fragment
//// Activity
public class RssfeedActivity extends Activity implements MyListFragment.OnItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rssfeed);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Annv - Fragment", "onClick here");
}
});
}
// if the wizard generated an onCreateOptionsMenu you can delete
// it, not needed for this tutorial
#Override
public void onRssItemSelected(String link) {
// DetailFragment fragment = (DetailFragment) getFragmentManager()
// .findFragmentById(R.id.detailFragment);
// if (fragment != null && fragment.isInLayout()) {
// fragment.setText(link);
// }
// Intent start = new Intent(this, RssfeedSecondActivity.class);
// startActivity(start);
DetailFragment fragment = (DetailFragment) getFragmentManager()
.findFragmentById(R.id.detailFragment);
if (fragment != null && fragment.isInLayout()) {
fragment.setText(link);
}
}
}
/// Fragment
public class MyListFragment extends Fragment {
private OnItemSelectedListener listener;
private OnItemStartActivityListener listenerStartAct;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_rsslist_overview,
container, false);
Button button = (Button) view.findViewById(R.id.button1);
Log.d("Annv - Fragment", "run on " + getActivity().toString());
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateDetail();
}
});
return view;
}
public interface OnItemSelectedListener {
public void onRssItemSelected(String link);
}
public interface OnItemStartActivityListener {
public void onRssStartActivity(String link);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof OnItemSelectedListener) {
Log.d("Annv - Fragment", "activity " + activity.getLocalClassName());
listener = (OnItemSelectedListener) activity;
} else if (activity instanceof OnItemStartActivityListener) {
Log.d("Annv - Fragment", "activity " + activity.getLocalClassName());
listenerStartAct = (OnItemStartActivityListener) activity;
} else {
throw new ClassCastException(activity.toString()
+ " must implemenet MyListFragment.OnItemSelectedListener");
}
}
// May also be triggered from the Activity
public void updateDetail() {
// create fake data
// String newTime = String.valueOf(System.currentTimeMillis());
// // Send data to Activity
// listenerStartAct.onRssItemSelected(newTime);
if (getActivity() instanceof OnItemSelectedListener) {
listener.onRssItemSelected("start start");
} else {
String newTime = String.valueOf(System.currentTimeMillis());
listenerStartAct.onRssStartActivity(newTime);
}
}
}