如何显示带有扩展 BaseActivity 的数据绑定的 childActivity?
How to show childActivity with databinding that extends BaseActivity?
我正在使用一个基础 activity 作为另一个 activity "RecicpeActivity" 的父级,因为我已经覆盖了基础 activity 中的方法 setContentView 以便子 activity 可以使用它并通过它的布局在框架布局中膨胀。
Child activity "RecicpeActivity" 使用 DataBinding 设置其视图。
我正在做的是我试图将子 activity 的布局膨胀到基础 activity 中的框架布局 "container" 但是数据绑定根本没有像我一样被考虑即使我在调试时看到子 activity 的布局作为框架布局的子布局,也有一个白色屏幕。
- 我试过两种方法:
1- 第一个我尝试简单地通过调用 setContentView 来传递子 activity 的布局,并将传递的布局膨胀到基础 activity 中的框架布局。
2-第二次我尝试在基础中使用数据绑定activity,但我认为这无关紧要。
_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 布局"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 布局"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 与数据绑定“第二种方式”
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);
}
充气后调用layout.requestLayout()
,以便它可以适应充气后所做的更改。
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.
如果您在调试时可以在视图层次结构中看到 child,那么这应该可以解决问题。
https://developer.android.com/reference/android/view/View.html#requestLayout()
第 2 部分:绑定不起作用
您正在膨胀视图两次,一次是在您的 child activity 中,一次是在您的 BaseActivity:
mBinding = DataBindingUtil.inflate(
getLayoutInflater(),
R.layout.activity_recipe, null, false);
setContentView(R.layout.activity_recipe);
mBinding 您为数据绑定膨胀了一次,然后将布局 ID 传递给 setContentView,它再次膨胀:
getLayoutInflater().inflate(layoutResID, frameLayout, true);
因此数据绑定中的视图与您添加到基本布局中的视图不同。
创建一个接受视图而不是 id 的 setContentView 的重载版本。
我正在使用一个基础 activity 作为另一个 activity "RecicpeActivity" 的父级,因为我已经覆盖了基础 activity 中的方法 setContentView 以便子 activity 可以使用它并通过它的布局在框架布局中膨胀。 Child activity "RecicpeActivity" 使用 DataBinding 设置其视图。 我正在做的是我试图将子 activity 的布局膨胀到基础 activity 中的框架布局 "container" 但是数据绑定根本没有像我一样被考虑即使我在调试时看到子 activity 的布局作为框架布局的子布局,也有一个白色屏幕。
- 我试过两种方法:
1- 第一个我尝试简单地通过调用 setContentView 来传递子 activity 的布局,并将传递的布局膨胀到基础 activity 中的框架布局。
2-第二次我尝试在基础中使用数据绑定activity,但我认为这无关紧要。
_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 布局"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 布局"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 与数据绑定“第二种方式”
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);
}
充气后调用layout.requestLayout()
,以便它可以适应充气后所做的更改。
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.
如果您在调试时可以在视图层次结构中看到 child,那么这应该可以解决问题。
https://developer.android.com/reference/android/view/View.html#requestLayout()
第 2 部分:绑定不起作用
您正在膨胀视图两次,一次是在您的 child activity 中,一次是在您的 BaseActivity:
mBinding = DataBindingUtil.inflate(
getLayoutInflater(),
R.layout.activity_recipe, null, false);
setContentView(R.layout.activity_recipe);
mBinding 您为数据绑定膨胀了一次,然后将布局 ID 传递给 setContentView,它再次膨胀:
getLayoutInflater().inflate(layoutResID, frameLayout, true);
因此数据绑定中的视图与您添加到基本布局中的视图不同。
创建一个接受视图而不是 id 的 setContentView 的重载版本。