strong textApp have a fragment that contains image and i want to pass the image to activity use Bitmap when i click to set this image as wallpaper.
From Fragment :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_view_pager, null);
ImageView resultView = (ImageView) view.findViewById(R.id.result_image);
resultView.setDrawingCacheEnabled(true);
bitmap = resultView.getDrawingCache();
resultView.setImageResource(pageNumber);
return view;
}
To Activity, when i click to set:
case R.id.setForce:
new TaskSetWallpaper(PreviewActivity.this).execute(bitmap);
break;
You can create an interface in your fragment, which the parent activity of the fragment is expected to implement. Then, you can cast the activity to the interface in onAttach() of the fragment and call methods in the interface to notify events or pass data to parent activity.
Fragment:
public class MyFragment extends Fragment {
private EventListener eventListener;
public interface EventListener() {
void onSetImage(Bitmap bitmap);
}
#Override
public void onAttach(Activity a) {
super.onAttach(a);
if (a instanceof EventListener) {
eventListener = (EventListener) a;
} else {
throw new UnsupportedOperationException("Parent activity should implement MyFragment.EventListener");
}
}
}
Parent activity:
public class ParentActivity extends AppCompatActivity implements MyFragment.EventListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
//---------
//---------
}
#Override
void onSetImage(Bitmap bitmap){
new TaskSetWallpaper(PreviewActivity.this).execute(bitmap);
}
}
Related
I have a DialogFragment with a ViewPager2:
public class LightboxFragment extends DialogFragment {
private ViewPager2 viewPager;
private MyViewPagerAdapter myViewPagerAdapter;
public static LightboxFragment newInstance() {
LightboxFragment fragment = new LightboxFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_lightbox, container, false);
viewPager = v.findViewById(R.id.viewPager);
FrameLayout closeButtonContainer = v.findViewById(R.id.close_button_container);
closeButtonContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
myViewPagerAdapter = new MyViewPagerAdapter(getActivity());
viewPager.setAdapter(myViewPagerAdapter);
return v;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public class MyViewPagerAdapter extends FragmentStateAdapter {
public MyViewPagerAdapter(FragmentActivity fa) {
super(fa);
}
#NonNull
#Override
public Fragment createFragment(int position) {
LightboxVideoFragment fragment = new LightboxVideoFragment();
return fragment;
}
#Override
public int getItemCount() {
return items.size();
}
}
}
And my LightboxVideoFragment looks something like this:
public class LightboxVideoFragment extends Fragment {
private SimpleExoPlayer exoPlayer;
private PlayerView playerView;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.slideshow_video, container, false);
}
#Override
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
playerView = view.findViewById(R.id.player_view);
MediaItem mediaItem = MediaItem.fromUri(media.getUrls().getMp4());
exoPlayer = new SimpleExoPlayer.Builder(getContext()).build();
exoPlayer.setRepeatMode(Player.REPEAT_MODE_ALL);
playerView.setPlayer(exoPlayer);
exoPlayer.setMediaItem(mediaItem);
exoPlayer.prepare();
exoPlayer.play();
}
#Override
public void onResume() {
super.onResume();
if (exoPlayer != null) {
exoPlayer.play();
}
}
#Override
public void onPause() {
super.onPause();
if (exoPlayer != null) {
exoPlayer.pause();
}
}
#Override
public void onDetach() {
super.onDetach();
if (exoPlayer != null) {
exoPlayer.release();
}
}
}
My problem is this: When the DialogFragment is dismissed, the audio from the fragment's video is still playing. Why is this? I've tried adding onDestroy in my fragment and setting breakpoints there, but the breakpoint is never called when the dialog is dismissed, nor is onPause or onDetach.
Does this also mean that the ExoPlayer instance is also still alive when the dialog is dismissed?
How can I stop the video's audio when the dialog is dismissed?
I don't use viewpager2 inside another Fragment but based on the documentation and the source code of viewpager2 I think you are creating the adapter incorrectly when doing it from a Fragment.
In the class LightboxFragment try changing line
myViewPagerAdapter = new MyViewPagerAdapter(getActivity());
to
myViewPagerAdapter = new MyViewPagerAdapter(this);
This is because based on the documentation https://developer.android.com/reference/androidx/viewpager2/adapter/FragmentStateAdapter#FragmentStateAdapter(androidx.fragment.app.Fragment)
Fragment: if the ViewPager2 lives directly in a Fragment subclass.
You are using it as if the Viewpager2 is living directly in the host activity.
This means you are putting LightboxVideoFragment in the same FragmentManager as LightboxFragment and the Lifecycle changes to LightboxFragment don't affect what are basically siblings to it (not children as they should be)
If you look at the source code of viewpager2 for the constructors as well
https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/viewpager2/viewpager2/src/main/java/androidx/viewpager2/adapter/FragmentStateAdapter.java#102
The correct constructor ties the Fragments in the viewpager2 adaptor to a host Fragment via getChildFragmentManager() and the Fragment's lifecycle and not to the Activity's lifecycle.
(I've not experimented or tested this just knowledge from the docs and reading the source code).
Suppose, I have two fragments , FragmentA and FragmentB inside viewpager .When i click the button in fragmentA then it should be able to add the textview in another fragmentB.so, how is it possible ....please help me out.
class Myadpter extends FragmentPagerAdapter {
Fragment fragment =null;
public Myadpter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if(position==0){
fragment = new Post();
}
if(position==1){
fragment = new ActiveChat();
}
if(position==2){
fragment = new LastUsers();
}
if(position==3){
fragment = new Noname();
}
return fragment;
}
#Override
public int getCount() {
return 4;
}
}
Implement a interface to communicate between two fragments, the class where the view pager is will be a middle man
As already stated by the other user, implementing an interface is the way to go. This link Communicating with Other Fragments will explain in more detail how to achieve what you are attempting to do. Hope this solves your problem.
Do as follows:
Fragment A
public class FragmentA extends Fragment implements View.OnClickListener {
OnButtonPressed mCallback;
Button yourButton;
TextView textViewFragA;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.your_layout, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
yourButton = findViewById(R.id.yourBtn);
textViewFragA = findViewById(R.id.textViewFragA);
yourButton.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.yourBtn:
mCallback.onButtonPressed(textViewFragA);
break;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnButtonPressed) getActivity();
} catch (ClassCastException e) {
throw new ClassCastException(getActivity().toString()
+ " must implement OnButtonPressed");
}
}
#Override
public void onDetach() {
mCallback = null; // Avoid memory leaking
super.onDetach();
}
/**
* Interface called whenever the user has clicked on the Button
* #param textView The TextView to add in FragmentB
*/
public interface OnButtonPressed{
void onButtonPressed(TextView textView);
}
}
FragmentB
public class FragmentB extends Fragment{
TextView textViewFragB;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.your_layout, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
textViewFragB= findViewById(R.id.textViewFragB);
}
public TextView getTextViewFragB(){
return textViewFragB;
}
Activity
public class TabControllerActivity extends AppCompatActivity implements FragmentA.OnButtonPressed{
MyAdapter adapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_activity_layout);
// Your Stuff
}
// Everytime the user clicks on the Button in FragmentA, this interface method gets triggered
#Override
public void onButtonPressed(TextView textViewFragA) {
FragmentB fragmentB = (FragmentB) adapter.getItem(1)/* Be careful here and get the right fragment,
otherwise the App will crash*/
// Since you got the TextView and not only the text inside of it,
// you can do whatever you want. Here for example we set the text like the textViewFragA.
//In a few words you turn the textViewFragB to the other one
fragmentB.getTextViewFragB().setText(textViewFragA.getText().toString());
}
}
Hope it will help
I have two fragments and I navigate by swiping between them. I want to update second fragment TextView from first fragment. Is it possibleto do that? Here's what I try to do but this doesn't worked to me.
public void updateOtherFragment(){
LayoutInflater inflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View vi = inflater.inflate(R.layout.fragment_log, null); //my second fragment xml file.
TextView tv = (TextView)vi.findViewById(R.id.textLog);
tv.setText("Updated from first fragment " + info.getName());
}
The default Google way for communication between fragments is to do that through the activity that hosts them.
The FirstFragment defines a callbacks interface that the activity must implement. When the activity gets a callback it can send the information through to the SecondFragment. Just read the example code below to make this more clear:
FirstFragment.java:
This fragment has a button, which when clicked sends a callback to its activity.
public class FirstFragment extends Fragment implements View.OnClickListener {
public FirstFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View result = inflater.inflate(R.layout.fragment_first, container, false);
result.findViewById(R.id.updateButton).setOnClickListener(this);
return result;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.updateButton:
((Callbacks) getActivity()).onUpdateLogtext("This is an update from FirstFragment");
break;
default:
throw new UnsupportedOperationException();
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof Callbacks))
throw new UnsupportedOperationException("Hosting activity must implement Callbacks interface");
}
public interface Callbacks {
void onUpdateLogtext(String text);
}
}
MainActivity.java:
This activity implements the FirstFragment.Callbacks interface in order to receive callbacks from FirstFragment. When it receives an onUpdateLogtext it just passes the data on to SecondFragment.
public class MainActivity extends AppCompatActivity implements FirstFragment.Callbacks {
private SecondFragment secondFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
secondFragment = (SecondFragment) getFragmentManager().findFragmentById(R.id.secondFragment);
}
#Override
public void onUpdateLogtext(String text) {
secondFragment.updateLogtext(text);
}
}
SecondFragment.java:
This just provides a public method that sets the textview with new data. And this method is used by MainActivity when it gets a onUpdateLogtext callback from FirstFragment.
public class SecondFragment extends Fragment {
private TextView tv;
public SecondFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View result = inflater.inflate(R.layout.fragment_second, container, false);
tv = (TextView) result.findViewById(R.id.textlog);
return result;
}
public void updateLogtext(String text) {
tv.setText(text);
}
}
I am developing an Android application. I have a requirement like there is a button in fragment 1, when a user clicks that button result should be displayed in fragment 2. While loading the activity both fragments is attached. Here is my try:
In main activity:
public void dsp(String str) {
secondfragment f2=new secondfragment();
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
f2.setArguments(bundle);
}
In first fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.fragone, container,false);
Button btn = (Button) v.findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
m.dsp("clicked");
}
});
return v;
}
In second fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.fragtwo, container,false);
tv= (TextView) v.findViewById(R.id.textView1);
tv.setText(this.getArguments().getString("name"));
return v;
}
When communicating from Fragment to Fragment you use an interface to pass data to the Activity which in turn updates the fragment you want to change.
For Example:
In Fragment 1:
public class FragmentOne extends Fragment{
public Callback mCallback;
public interface Callback{
void onUpdateFragmentTwo(String message);
}
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
mCallback = (Callback) activity;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.fragone, container,false);
Button btn = (Button) v.findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mCallback.onUpdateFragmentTwo("clicked");
}
});
return v;
}
}
then in main Activity implement the interface:
public class MainActivity extends AppCompatActivity implements Callback{
FragmentTwo fragmentTwo;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// ... Load views or perform logic
// ... Load Fragment Two into your container
if(savedInstanceState == null){
fragmentTwo = FragmentTwo.newInstance(new Bundle()); // use real bundle here
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_holder, fragmentTwo, "Frag2").commit();
}
}
// Interface method
#Override
public void onUpdateFragmentTwo(String message){
// Call activity method with the argument
if(fragmentTwo != null){
fragmentTwo.updateFragmentTwo(message);
}
}
}
Update
In your second fragment I typically use a static newInstance(Bundle args) method to initialize and then would use a public method to communicate from the Activity to the Fragment for example:
public class FragmentTwo extends Fragment{
public static FragmentTwo newInstance(Bundle args){
FragmentTwo fragment = new FragmentTwo();
fragment.setArguments(args);
return fragment;
}
//... Class overrides here onCreateView etc..
// declare this method
public void updateFragmentTwo(String updateText){
// .. do something with update text
}
}
Thats it, happy coding!
Here you have what the Android Documentation says about Communicating Between Fragments. Here you'll have all the necessary steps to make two or more fragments communicate securely :)
Hello I am using Fragment in my android application. I need to get the view which I can get using.
mNoteEditText = rootView.findViewById(R.id.noteEditText);
This mNoteEditText is require to access in onBackPressed so every view reference I need to make them static variable because of Fragment class is static. I know to make every view to static variable is not good approach. How this I can make such that I dont need to make any static variable of the view.
public class NotesActivity extends Activity {
private int bookId;
private int chapterId;
private static EditText mNoteEditText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notes);
// get data from intent that sent from home activity
bookId = getIntent().getIntExtra("book_id", -1);
chapterId = getIntent().getIntExtra("book_id", -1);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new NoteFragment()).commit();
}
}
/**
* A note fragment containing a note layout.
*/
public static class NoteFragment extends Fragment {
public NoteFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_notes,
container, false);
mNoteEditText = (EditText) rootView.findViewById(R.id.noteEditText);
return rootView;
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
// get database instance
MySQLiteOpenHelper db = MySQLiteOpenHelper.getInstance(this);
Notes note = new Notes();
note.setBookId(bookId);
note.setChapterId(chapterId);
note.setNote(mNoteEditText.getText().toString());
}
}
Please help and thanks in advance.
A Fragment has a Method called getView(). With it you can get the View of the Fragment as long as it is attached to an Activity.
View view = fragment.getView();
But if you are looking for a View inside the Fragment you can also just get it with findViewById() from the Activity. Again the Fragment has to be attached to the Activity for this to work.
BUT you should not do that. Nothing outside the Fragment should have anything to do with something inside the Fragment. Write public methods in the Fragment to interact with it. Try something like this:
public static class NoteFragment extends Fragment {
private EditText noteEditText;
public NoteFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_notes, container, false);
this.noteEditText = (EditText) rootView.findViewById(R.id.noteEditText);
return rootView;
}
// I added the following 3 methods to interact with the Fragment
public boolean isEmpty() {
final String text = this.noteEditText.getText().toString();
return text.isEmpty();
}
public String getText() {
return this.noteEditText.getText().toString();
}
public void setText(String text) {
this.noteEditText.setText(text);
}
}
And now in your Activity you can do this:
public class NotesActivity extends Activity {
private int bookId;
private int chapterId;
private NoteFragment noteFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notes);
// get data from intent that sent from home activity
bookId = getIntent().getIntExtra("book_id", -1);
chapterId = getIntent().getIntExtra("book_id", -1);
if (savedInstanceState == null) {
this.noteFragment = new NoteFragment();
getFragmentManager().beginTransaction().add(R.id.container, this.noteFragment).commit();
}
// Now you can interact with the Fragment
this.noteFragment.setText("some text");
...
if(!this.noteFragment.isEmpty()) {
String note = this.noteFragment.getText();
...
}
}
}