RecycleView item transition to fragment - android

I am trying to create image move transition from recycle view to fragment. But the problem is that after the transition image is displayed in the new the move animation doesn't happen it just fades in with the rest of the content. What could I be doing wrong. I was following this example:
http://mikescamell.com/shared-element-transitions-part-4-recyclerview/
I have recycle view item layout with image view:
<?xml ...?>
<layout ...>
<data>
<variable name="model" type="..."/>
</data>
<LinearLayout ...>
<FrameLayout ...>
<ImageView android:id="#+id/image" .../>
</FrameLayout>
<LinearLayout ...>
...
</LinearLayout>
</LinearLayout>
</layout>
And then I have a fragment layout to which I want to move the image from recycle view.
<FrameLayout ...>
<TextView .../>
<ImageView android:id="#+id/logo" >
</FrameLayout>
Here's recycle my view onBindViewHolder method
#Override
public void onBindViewHolder(RecycleViewAdapter.ViewHolder holder, int position) {
final T object = getItem(position);
holder.getBinding().setVariable(BR.model, object);
holder.getBinding().executePendingBindings();
ViewCompat.setTransitionName(holder.getBaseView().findViewById(R.id.logo), "wb_logo");
holder.getBaseView().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onItemClickListener.onItemClick(view, object);
}
});
}
Here's recycle view item click handler in my main activity
#Override
public void onFragmentItemClick(View view, Object object) {
PreviewFragment fragment = PreviewFragment.newInstance(Object.imageId, "");
getFragmentManager()
.beginTransaction()
.addSharedElement(view.getRootView().findViewById(R.id.logo), "wb_logo")
.addToBackStack(null)
.replace(R.id.fragment_container, fragment)
.commit();
}
In my fragment class in which I wan't to animate image I have following setup:
#Override
public void onCreate(Bundle savedInstanceState) {
...
setSharedElementEnterTransition(
TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move));
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ImageView imageView = view.findViewById(R.id.logo);
imageView.setTransitionName("wb_logo");
imageView.setImageResource(...);
}
I tried statically adding transitionName attribute to image views but the result was same.
Edit
Maybe there is something wrong with my general layout. My fragment container is in a DrawerLayout
<android.support.v4.widget.DrawerLayout ...>
<android.support.design.widget.CoordinatorLayout ...>
<android.support.design.widget.AppBarLayout ...>
<android.support.v7.widget.Toolbar ... />
</android.support.design.widget.AppBarLayout>
<FrameLayout android:id="#+id/fragment_container" .../>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView .../>
</android.support.v4.widget.DrawerLayout>
Or fragment class I am using I am using
android.app.Fragment
instead of
android.support.v4.app.Fragment
within
android.support.v7.app.AppCompatActivity

I figured out what was my problem: I had multiple items in recycle view which all had ImageView inside them with android:transitionName="wb_logo".
I somehow missed the point that each shared item in recycle view must have a unique transitionName. when I modified transitionName to include id suffix it started working as intended.
android:transitionName="wb_logo_1"
android:transitionName="wb_logo_2"

Try setting the transition name in xml rather than JAVA side. I think it might not be working because you are setting it when the view is already created.
<ImageView
android:id="#+id/ivItem"
android:transitionName="wb_logo"
android:layout_width="match_parent"
android:background="#android:color/holo_blue_bright"
android:scaleType="centerCrop"
android:layout_height="wrap_content" />
The above would be in your item in your recycler view.
<ImageView
android:id="#+id/wb_logo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:transitionName="wb_logo" />
The above would then be in your fragment
Your start fragment code is correct

Related

How to show childActivity with databinding that extends BaseActivity?

I am using a base activity as a parent of another activity "RecicpeActivity" as I have overridden the method setContentView in the base activity so that the child activity can use it and pass its layout to be inflated in the frame layout.
The Child activity "RecicpeActivity" uses DataBinding to set its views.
What I am doing is I am trying to inflate the layout of the child activity into a frame layout "container" in the base activity BUT the data binding is not being considered at all as I am having a white screen even though I have seen the layout of the child activity as a child of the frame layout while debugging.
I have tried two ways:
1- The first one I have tried to pass the layout of the child activity simply by calling setContentView and inflated the passed layout to the frame layout in the base activity.
2- The second on I have tried to use data binding in the base activity, But I don't think it would matter.
_ChildActivity
public class RecipeActivity extends BaseActivity {
private ActivityRecipeBinding mBinding;
private static final String RECIPE_INTENT_KEY = "recipe key";
private ScrollView mScrollView;
private RecipeViewModel recipeViewModel;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
recipeViewModel =
ViewModelProviders.of(this).get(RecipeViewModel.class);
mBinding = DataBindingUtil.inflate(
getLayoutInflater(),
R.layout.activity_recipe, null, false);
setContentView(R.layout.activity_recipe);
// This method is implemented in the BaseActivity.
showProgressBar(true);
recipeViewModel.getRecipe().observe(this, new Observer<Recipe>() {
#Override
public void onChanged(Recipe recipe) {
if (recipe != null){
if (recipe.getRecipe_id().equals(
recipeViewModel.getRecipeId())){
mBinding.setRecipe(recipe);
mScrollView.setVisibility(View.VISIBLE);
showProgressBar(false);
}
}
}
});
recipeViewModel.getRecipeById(getIncomingIntentRecipeId());
}
private String getIncomingIntentRecipeId(){
if (getIntent().hasExtra(RECIPE_INTENT_KEY)){
String recipe_id = getIntent().getStringExtra(RECIPE_INTENT_KEY);
return recipe_id;
}
return null;
}
_BaseActivity
public abstract class BaseActivity extends AppCompatActivity {
public ProgressBar mProgressBar;
#Override
public void setContentView(int layoutResID) {
RelativeLayout mRelativeLayout =
(RelativeLayout) getLayoutInflater().inflate(
R.layout.activity_base, null);
FrameLayout frameLayout = mRelativeLayout.findViewById(
R.id.activity_content);
mProgressBar = mRelativeLayout.findViewById(R.id.progress_bar)
/**
* True means layoutResID should be inflated and made a part of
parent frameLayout
*/
getLayoutInflater().inflate(layoutResID, frameLayout, true);
super.setContentView(mRelativeLayout);
}
public void showProgressBar(boolean visibility){
mProgressBar.setVisibility(visibility ?
View.VISIBLE : View.INVISIBLE);
}
_ChildActivity Layout "activity_recipe"
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="recipe"
type="com.mustafa.foodapp.models.Recipe" />
<import type="com.mustafa.foodapp.util.StringUtils" />
</data>
<ScrollView
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/recipe_image"
android:layout_width="match_parent"
android:layout_height="#dimen/recipe_image_height"
android:scaleType="center"
app:imageUrl="#{recipe.image_url}" />
<TextView
android:id="#+id/recipe_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/recipe_image"
android:padding="7dp"
android:text="#{recipe.title}"
android:textColor="#000"
android:textSize="#dimen/recipe_title_text_size" />
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/recipe_title"
android:orientation="horizontal"
android:padding="10dp"
android:weightSum="100">
<TextView
android:id="#+id/recipe_social_score"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="10"
android:gravity="center"
android:text="#{String.valueOf(
Math.round(recipe.social_rank))}"
android:textColor="#color/red"
android:textSize="#dimen/
recipe_publisher_text_size"/>
</LinearLayout>
<LinearLayout
android:id="#+id/ingredients_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/container"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{StringUtils.getStringIngredients(
recipe.ingredients)}" />
</LinearLayout>
</RelativeLayout>
</ScrollView>
</layout>
_BaseActivity Layout "activity_base"
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/base_relative_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/activity_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<ProgressBar
android:id="#+id/progress_bar"
style="#style/Widget.AppCompat.ProgressBar"
android:layout_width="125dp"
android:layout_height="125dp"
android:layout_centerInParent="true"
android:visibility="gone" />
</RelativeLayout>
_BaseActivity with data-binding "2nd way"
public abstract class BaseActivity extends AppCompatActivity {
public ProgressBar mProgressBar;
public ActivityBaseBinding baseBinding;
#Override
public void setContentView(int layoutResID) {
baseBinding = DataBindingUtil.inflate(
getLayoutInflater(), R.layout.activity_base, null, false);
mProgressBar = baseBinding.progressBar;
/**
* True means layoutResID should be inflated and made a part of the
parent frameLayout
*/
getLayoutInflater().inflate(layoutResID, baseBinding.activityContent,
true);
super.setContentView(baseBinding.getRoot());
}
public void showProgressBar(boolean visibility){
mProgressBar.setVisibility(visibility ?
View.VISIBLE : View.INVISIBLE);
}
Call layout.requestLayout() after inflating so it can adjust to the changes made after inflating.
getLayoutInflater().inflate(layoutResID, baseBinding.activityContent, true);
mRelativeLayout.requestLayout();
super.setContentView(baseBinding.getRoot());
public void requestLayout ()
Call this when something has changed which has invalidated the layout of this view. This will schedule a layout pass of the view tree.
If you can see the child in view heirarchy while debugging, then this should fix the issue.
https://developer.android.com/reference/android/view/View.html#requestLayout()
PART 2: Binding Doesn't work
You are inflating view two times, once in your child activity, and once in your BaseActivity:
mBinding = DataBindingUtil.inflate(
getLayoutInflater(),
R.layout.activity_recipe, null, false);
setContentView(R.layout.activity_recipe);
mBinding You inflated once for databinding, then you passed layout id to setContentView where it inflated again:
getLayoutInflater().inflate(layoutResID, frameLayout, true);
So the one in Databinding is a different view from the one you added to base layout.
Create an Overloaded version of setContentView that accepts view instead of id.

How to write an espresso test case for a fragment container with recyclerview click item action

I have an activity which has a fragment container which loads a fragment with recyclerview. On clicking any of the recycler view items, it will open a new activity. I want to write an espresso test case for this scenario.
My Activity:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/background">
<FrameLayout
android:id="#+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:layout_weight="1">
</FrameLayout>
My Fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
android:layout_margin="16dp"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_items"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MyTestCase:
#RunWith(AndroidJUnit4.class)
public class MainActivityTest {
#Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
#Before
public void init() {
mActivityTestRule.getActivity()
.getSupportFragmentManager().beginTransaction();
}
#Test
public void recyclerview_clickTest() {
/* onView(withId(R.id.fragmentContainer)).perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
onView(withText("Alpha")).perform(click());
onView(allOf(instanceOf(TextView.class), withParent(withResourceName("action_bar"))))
.check(matches(withText("Alpha")));*/
onData(allOf(is(new BoundedMatcher<Object, MyModel>(MyModel.class) {
#Override
public void describeTo(Description description) {
}
#Override
protected boolean matchesSafely(MyModel abc) {
return onView(allOf(instanceOf(TextView.class), withParent(withResourceName("action_bar"))))
.check(matchesSafely(withResourceName(abc)));
}
})));
}
}
TIA.
You can use ViewMatchers for this action
Example
onView(withId(R.id.your_recycler_view)).perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
Try the following
onView(allOf(isDisplayed(), withId(R.id.your_recycler_view))).perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
If the above still does not work and you're sure that the recycler view is on display then launch UIAutomator and try to highlight above your recycler view, check if the thing it highlights is your recycler view, chances are your recycler view might have something on top of it which makes it not clickable (or it might not even be on display).
Another thing to check is if there is a transition and no animation is in place, the test might be looking for your recycler view while it is not yet on display. You might want to check on https://developer.android.com/training/testing/espresso/idling-resource
For a quicker check, just make the thread sleep prior to clicking on the recycler view
Thread.sleep(timeMs, timeout)

Reapprove layout with butterknife

I have a BaseActivity that contains this structure:
<!-- activity_base -->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="#+id/container_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<include
layout="#layout/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<include
layout="#layout/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tool_bar"
android:layout_above="#id/bottom_navigation" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_navigation_menu" />
</RelativeLayout>
In my BaseActivity I'm controlling the BottomNavigationView. And I created several Activities where I would like to take advantage of the include content and load only the contents of that activity.
Today the project is using butterknife Java. And the project is getting giant because it is replicating the top structure of the BaseActivity for each sub activity. I would like to refactor (in the best and quickest possible way) the project so that there is only one
activity_base.xml and other activities control only its content (content.xml).
I saw something using ViewStub and another describing <merge> but I did not understand how to apply the concepts easily in the project since many use activity and fragment, my project is only with activities.
I'm not completely happy with this solution but I ended up with something like that working on a similar case:
base_activity.xml
<...>
..... Whatever you want at the top
<.../>
<!-- Container where your child Activity layout will be inflated -->
<FrameLayout
layout="#+id/child_activity_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<...>
..... Whatever you want at the bottom
<.../>
BaseActivity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
ViewGroup parent = findViewById(R.id.child_activity_container);
View childView = inflateChildLayout(LayoutInflater.from(this), parent);
// The child Activity can have no layout (for some reason)
if (childView != null) {
parent.addView(childView);
}
ButterKnife.bind(BaseActivity.this);
// ... the rest of your onCreate
}
#Nullable
protected abstract View inflateChildLayout(LayoutInflater inflater, ViewGroup parent);
ChildActivity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(...); // Already managed by the base Activity so we don't need it
}
#Override
protected View inflateChildLayout(LayoutInflater inflater, ViewGroup parent) {
return inflater.inflate(R.layout.activity_child, parent, false);
}
The idea is the BaseActivity manage the inflation of the child layout inside its own layout and manage the call to ButterKnife. As the parent and the child are in reality the same instance (as ChildActivity extends BaseActivity) ButterKnife both the parent and the child Views. That's why it's called after the call to inflateChildLayout

View on top of map disappears while using it with a DrawerLayout

I'm creating a layout which contains a maps (com.google.android.gms.maps.SupportMapFragment) & a mini layout to enter origin & destination(pickup_dropoff_LL LinearLayout).
XML
<RelativeLayout
android:id="#+id/main_RL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/rideType_LL">
<include
android:id="#+id/pickup_dropoff_LL"
layout="#layout/layout_pickup_dropoff"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp" />
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
</RelativeLayout>
Initially this had a corresponding Activity but I had to introduce a DrawerLayout so I had to convert it to a Fragment.
After doing that my pickup_dropoff_LL disappears.
It is shown on the screen for a micro second and then it disappears.
I suspect the issue is somewhere here but I'm not sure.
SupportMapFragment fm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_main_activity, container, false);
fm = new SupportMapFragment() {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
map = fm.getMap();
if (map != null) {
map.setMyLocationEnabled(true);
fm.getMapAsync(MainActivity2.this);
}
}
};
getChildFragmentManager().beginTransaction().add(R.id.main_RL, fm).commit();
return rootView;
}
1. I checked visibility for pickup_dropoff_LL. It's showing as 0, which means View.VISIBLE. But it is not visible.
2. As suggested by some links, I tried placing an empty view of same height & width over my map. Even that didn't work.
So how do I stop the view from disappearing?? Please help.
Try drawing your layout last. Put the Include after the Fragment
<RelativeLayout
android:id="#+id/main_RL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/rideType_LL">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
<include
android:id="#+id/pickup_dropoff_LL"
layout="#layout/layout_pickup_dropoff"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp" />
</RelativeLayout>
Have you tried moving your content inside of your drawer and not behind it?
<!-- Drawer Host inside the parent relative layout -->
<android.support.v4.widget.DrawerLayout
android:id="#+id/main_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Hold Fragment here -->
<FrameLayout
android:id="#+id/frag_main_host"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- Drawer -->
<RelativeLayout
android:id="#+id/drawer_pane"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start">
<!-- Menu list for drawer -->
<ListView
android:id="#+id/menu_list"
android:layout_height="match_parent"
android:layout_width="280dp"
android:dividerHeight="1sp"
android:gravity="start"
android:choiceMode="singleChoice" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
Putting anything below your view would make it not appear when opened although it is visible in property. In your class you can swap the fragment as desired by calling the fragment manager and seleting a fragment at whatever list index is selected. I suggest use an internal listener and just call a method to pick the view and swap it. Like below:
Listener (Internal class):
class MainDrawerItemClickListener implements AdapterView.OnItemClickListener{
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long id ){
getView(position);
// close the drawers once selected
mDrawerLayout.closeDrawers();
}
}
That method will call this method in your main class:
// select the view
public void getView( int position ){
Fragment frag = null;
switch( position ){
case 0:
frag = new MyFragment();
break;
case 1:
frag = new MyOtherFragment();
break;
default:
break;
}
if( frag != null ){
swapView( frag );
}
}
// swaps the fragments
public void swapView( Fragment frag ){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace( R.id.frag_main_host, frag ).commit();
}
Hope it helps, I know this is an old question, but I am sure someone will have the same question.

Android: Change Background Color of Fragment

I tried changing the background color of a fragment, but a small problem occurred.
public class MainActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
So, shown above is the code I had for my main class that calls the XML file for the fragment.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<fragment
android:id="#+id/fragment1"
android:name="com.northreal.practice.FirstFragment"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#CBA" />
</LinearLayout>
Above is the main.xml layout that is called by the main class (MainActivity).
public class FirstFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.main, parent, false);
}
}
Above the XML file with the fragment calls this class.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BLAHHHH"
android:layout_gravity="center_vertical" />
</LinearLayout>
This layout above is inflated by the class FirstFragment
So, why doesn't this actually change the color of the background of my fragment?
Fragments don't inherit from View and thus don't have a set background method.
Any easy fix is to just grab the root view of fragment and set its background
fragment.getView().setBackgroundColor(Color.WHITE);
The reason why that doesn't work is because fragment is treated similar to an activity. It is a container that is the child of the main activity, and is used to display other items.
You need to put the android:background="#CBA" in the actual layout that holds the TextView and NOT the fragment itself.
Like so:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CBA"
android:orientation="horizontal" >
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="BLAHHHH" />
</LinearLayout>
Get the fragment object like:
Fragment fragment = (Fragment) getFragmentManager().findFragmentById(R.id.fragmentId);
Change it's background like:
fragment.getView().setBackgroundColor(Color.WHITE);
In AndroidX you can use a FragmentContainerView instead of a Fragment to set a background:
<androidx.fragment.app.FragmentContainerView
...
android:background="#FFFFFF"/>
I have faced the same problem but my requirement was to set or change background drawable image of fragment. As Adam answered the approach is right and I would like to show the connection from fragment to activity.
The best practice is to use an interface named 'Connector'(or any name).Then from your fragment:
Connector connector = (Connector) getActivity();
connector.setIt(this);
Then in your activity which will implement 'Connector' interface and have the method.
#Override
public void setIt(Fragment fragment){
FirstFragment firstFrag = (FirstFragment) getSupportFragmentManager().findFragmentByTag("first");
firstFrag.getView().setBackgroundDrawable(getResources().getDrawable(R.drawable.app_background));
//or for color set
firstFrag.getView().setBackgroundColor(Color.WHITE);
}

Categories

Resources