Reputation: 3149
In my activity's layout, I have a view which I'd want to access from its attached fragment.
How could I do it?
Normally, from a fragment, to find a view defined in a fragment's layout (so it's another use case), I just use the inflater
to inflate the fragment's layout, and call findVieById
.
But since my view is defined in the activity's layout, I can't do this.
Could I use getActivity().findViewById
?
Upvotes: 0
Views: 86
Reputation: 81539
In my activity's layout, I have a view which I'd want to access from its attached fragment.
No, you don't want to.
How could I do it?
getActivity().findViewById(R.id.blah)
, but you shouldn't.
But since my view is defined in the activity's layout, I can't do this.
Technically you can, you just shouldn't.
Could I use getActivity().findViewById?
Yes, but you shouldn't.
As for the correct answer, this is why they created Android Architecture Components: ViewModel / LiveData
- so that you wouldn't be tempted to access views directly. You could modify the data/state shared via ViewModel in one place, and thanks to LiveData all observers would be updated with it.
Therefore you never have to touch views directly, you just need to update data.
public class MyActivity extends AppCompatActivity {
private MyViewModel myViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
myViewModel.myData().observe(this, (data) -> {
if(data == null) return;
updateViews(data);
});
}
}
and
public class MyViewModel extends ViewModel {
public MyViewModel() {}
private MutableLiveData<MyData> mutableData = new MutableLiveData<>();
public LiveData<MyData> myData() {
return mutableData;
}
public void updateData(MyData newData) {
mutableData.postValue(newData);
}
}
and
public class MyFragment extends Fragment {
private MyViewModel myViewModel;
@Override
protected void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
myViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
myViewModel.myData().observe(getViewLifecycleOwner(), (data) -> {
if(data == null) return;
updateViews(data);
});
}
}
This way:
you don't need to mess with interfaces like it would say in the official "fragment communication guide"
you don't need to touch views directly, just touch data
you keep up with the best practices introduced in 2017 (see also this video and this video from Google I/O 2017)
You can also find this technique in the official guides here.
Upvotes: 1
Reputation: 1375
It's not a good practice. You shouldn't do that. The Activity should handle its view on it own and you can trigger that handle function using an interface. Check this out.
https://developer.android.com/training/basics/fragments/communicating
Upvotes: 1
Reputation: 8305
Do this:
((YourActivityName)getActivity()).findViewById
or you can do findViewById
for a view and make it global in your activity and can access it like:
((YourActivityName)getActivity()).viewName
Upvotes: 0