I have 2 layout files. One is the default one, and the other is sw720dp
. Obviously, they both share the same model:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="java.lang.String" />
<variable
name="product"
type="com.test.test.test.test.Product" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical"
tools:context="com.test.test.test.test.ProductDetailsFragment">
<RelativeLayout
android:id="@+id/ll_custome_action_bar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@color/light_blue_900"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_back_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:gravity="center_vertical"
android:padding="16dp"
android:text="@string/fa_arrow_left"
android:textColor="@color/white"
android:textSize="22sp" />
<TextView
android:id="@+id/tv_product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingLeft="46dp"
android:paddingRight="46dp"
android:text="@{product.name}"
android:textColor="@color/white"
android:textSize="18sp" />
</RelativeLayout>
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/vp_product_images"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_below="@+id/ll_custome_action_bar"
fresco:actualImageScaleType="centerCrop"
fresco:placeholderImage="@drawable/placeholder2" />
<Button
android:id="@+id/btn_add_to_card"
android:layout_width="232dp"
android:layout_height="wrap_content"
android:layout_below="@+id/btn_wishlist"
android:layout_centerHorizontal="true"
android:layout_marginBottom="16dp"
android:background="@drawable/selector_button_green"
android:text="@string/add_to_cart"
android:textColor="@color/white"
android:textSize="16sp" />
<Button
android:id="@+id/btn_wishlist"
android:layout_width="232dp"
android:layout_height="wrap_content"
android:layout_below="@+id/ll_price_holder"
android:layout_centerHorizontal="true"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:background="@drawable/selector_button_red"
android:text="@string/wishlist"
android:textColor="@color/white"
android:textSize="16sp" />
<LinearLayout
android:id="@+id/ll_product_info_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/ll_product_images"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="5dp"
android:background="@drawable/drawable_border"
android:orientation="vertical">
<TextView
android:id="@+id/tv_product_description_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/light_blue_900"
android:gravity="center"
android:padding="3dp"
android:text="@string/description"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_product_description_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@{product.description}"
android:textColor="@color/gray_800"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_price_holder"
android:layout_width="264dp"
android:layout_height="wrap_content"
android:layout_below="@+id/ll_product_info_holder"
android:layout_centerHorizontal="true"
android:gravity="center"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/ll_total_price_holder"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/screen_edge_margin"
android:background="@drawable/drawable_border"
android:orientation="vertical">
<TextView
android:id="@+id/tv_total_price_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/light_blue_900"
android:gravity="center"
android:padding="3dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="@string/basePrice"
android:textColor="@color/white"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp">
<TextView
android:id="@+id/tv_total_price_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@{product.normalPrice}"
android:textColor="@color/gray_800"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/blank_space"
android:textColor="@color/white"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_total_price_currency"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@{product.productionData}"
android:textColor="@color/gray_800"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_your_price_holder"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/screen_edge_margin"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:background="@drawable/drawable_border"
android:orientation="vertical">
<TextView
android:id="@+id/tv_your_price_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/light_blue_900"
android:gravity="center"
android:padding="3dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="@string/yourPrice"
android:textColor="@color/white"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp">
<TextView
android:id="@+id/tv_your_price_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@{product.specialPrice}"
android:textColor="@color/gray_800"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/blank_space"
android:textColor="@color/white"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_your_price_currency"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@{product.productionData}"
android:textColor="@color/gray_800"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_product_images"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/vp_product_images"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="20dp"
android:orientation="horizontal">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/vp_product_image_1"
android:layout_width="100dp"
android:layout_height="70dp"
android:layout_margin="5dp"
android:layout_weight="1"
fresco:actualImageScaleType="centerCrop"
fresco:placeholderImage="@drawable/placeholder2" />
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/vp_product_image_2"
android:layout_width="100dp"
android:layout_height="70dp"
android:layout_margin="5dp"
android:layout_weight="1"
fresco:actualImageScaleType="centerCrop"
fresco:placeholderImage="@drawable/placeholder2" />
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/vp_product_image_3"
android:layout_width="100dp"
android:layout_height="70dp"
android:layout_margin="5dp"
android:layout_weight="1"
fresco:actualImageScaleType="centerCrop"
fresco:placeholderImage="@drawable/placeholder2" />
</LinearLayout>
</RelativeLayout>
</ScrollView>
Then, in my fragment I access the binder like this FragmentProductDetailsBinding mBinder
and later on mBinder.setProduct(mProduct);
.
public class ProductDetailsFragment extends BaseFragment implements ProductDetailsView {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public static final String ACTION_SHOW_ACTION_BAR = ProductDetailsFragment.class.getName() + ".show_action_bar";
public static final String ACTION_HIDE_ACTION_BAR = ProductDetailsFragment.class.getName() + ".hide_action_bar";
public static final String ACTION_BACK = ProductDetailsFragment.class.getName() + ".back";
public static final String ACTION_ADD_TO_CART = ProductDetailsFragment.class.getName() + ".add_to_cart";
public static final String ACTION_ADD_TO_WISHLIST = ProductDetailsFragment.class.getName() + ".add_to_wishlit";
FragmentProductDetailsBinding mBinder;
Shop mShop;
Product mProduct;
ProductDetailsPresenter mPresenter;
PreferenceAdapter mPreferenceAdapter;
public ProductDetailsFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param product Parameter 1.
* @return A new instance of fragment ProductDetailsFragment.
*/
public static ProductDetailsFragment newInstance(Shop shop, Product product) {
ProductDetailsFragment fragment = new ProductDetailsFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_PARAM1, Parcels.wrap(shop));
args.putParcelable(ARG_PARAM2, Parcels.wrap(product));
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
Parcelable parcelable;
parcelable = getArguments().getParcelable(ARG_PARAM1);
mShop = Parcels.unwrap(parcelable);
parcelable = getArguments().getParcelable(ARG_PARAM2);
mProduct = Parcels.unwrap(parcelable);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mBinder = DataBindingUtil.inflate(inflater, R.layout.fragment_product_details, container, false);
setUIListeners();
mPresenter = new ProductDetailsPresenterImpl(this);
mPreferenceAdapter = new PreferenceAdapter(getContext());
mBinder.setProduct(mProduct);
setImages();
setPriceVisibility();
sendActionToActivity(ACTION_HIDE_ACTION_BAR);
if (isUserLogged()) {
mBinder.btnWishlist.setVisibility(View.VISIBLE);
} else {
mBinder.btnWishlist.setVisibility(View.GONE);
}
return mBinder.getRoot();
}
@Override
public void onDestroyView() {
super.onDestroyView();
mPresenter.cleanup();
sendActionToActivity(ACTION_SHOW_ACTION_BAR);
}
@Override
protected void setTypeface() {
mBinder.tvBackButton.setTypeface(FontManager.getInstance().getFontAwesome());
}
private void setUIListeners() {
mBinder.btnAddToCard.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendActionToActivity(ACTION_ADD_TO_CART, mShop, mProduct);
}
});
mBinder.btnWishlist.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendActionToActivity(ACTION_ADD_TO_WISHLIST, mShop, mProduct);
}
});
mBinder.tvBackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendActionToActivity(ACTION_BACK);
}
});
}
private void setImages() {
String imagePathMax = mPreferenceAdapter.readImagePathMax();
String imagePathNormal = mPreferenceAdapter.readImagePathNormal();
String imageExtension = mPreferenceAdapter.readImageExtension();
String input = mProduct.getId();
input = input.replace(" ", "");
String image = imagePathMax + input + imageExtension;
String image_01 = imagePathNormal + input + "_01" + imageExtension;
String image_02 = imagePathNormal + input + "_02" + imageExtension;
final Uri imageUri = Uri.parse(image);
final Uri image_01Uri = Uri.parse(image_01);
final Uri image_02Uri = Uri.parse(image_02);
mBinder.vpProductImages.setImageURI(imageUri);
mBinder.vpProductImage1.setImageURI(imageUri);
mBinder.vpProductImage2.setImageURI(image_01Uri);
mBinder.vpProductImage3.setImageURI(image_02Uri);
mBinder.vpProductImage1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mBinder.vpProductImages.setImageURI(imageUri);
}
});
mBinder.vpProductImage2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mBinder.vpProductImages.setImageURI(image_01Uri);
}
});
mBinder.vpProductImage3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mBinder.vpProductImages.setImageURI(image_02Uri);
}
});
}
private void setPriceVisibility() {
if (mBinder.getProduct().getNormalPrice().equals(mBinder.getProduct().getSpecialPrice())) {
mBinder.llTotalPriceHolder.setVisibility(View.VISIBLE);
mBinder.llYourPriceHolder.setVisibility(View.GONE);
} else {
mBinder.llTotalPriceHolder.setVisibility(View.VISIBLE);
mBinder.llYourPriceHolder.setVisibility(View.VISIBLE);
}
}
@Override
public void logoutShop(Shop shop) {
}
@Override
public void showError(Error error) {
}
@Override
public void showProgress(boolean show) {
}
private void sendActionToActivity(String action) {
if (mListener == null) {
return;
}
Bundle bundle = new Bundle();
bundle.putString(Constants.ACTION_KEY, action);
mListener.onFragmentInteraction(bundle);
}
private void sendActionToActivity(String action, Shop shop, Product product) {
if (mListener == null) {
return;
}
Bundle bundle = new Bundle();
bundle.putString(Constants.ACTION_KEY, action);
bundle.putParcelable(Constants.DATA_KEY_1, Parcels.wrap(shop));
bundle.putParcelable(Constants.DATA_KEY_2, Parcels.wrap(product));
mListener.onFragmentInteraction(bundle);
}
public void logoutShop() {
AsyncExecutor.create().execute(new AsyncExecutor.RunnableEx() {
@Override
public void run() throws Exception {
mPresenter.logoutShop(mShop);
ShopRepository shopRepository;
shopRepository = new ShopRepository();
mShop.setLoginId(-1);
mShop.setCustomerId(-1);
mShop.setCartNumber(0);
mShop.setLineNumber(0);
mShop.setCartItems(0);
shopRepository.updateLoginNumber(mShop);
shopRepository.updateCart(mShop);
notifyChanges();
}
});
}
private boolean isUserLogged() {
return mShop != null && mShop.getLoginId() != -1;
}
private void notifyChanges() {
AuthShopResult event;
event = new AuthShopResult();
event.setShop(mShop);
EventBus.getDefault().post(event);
}
}
But when I try to run my app on tablet, and expect that the other layout is used, but I get an error at the binder.
C:\ProductDetailsFragment.java Error:(179, 65) error: cannot find symbol method getProduct() Error:(179, 20) error: cannot find symbol method getProduct() Error:Execution failed for task ':app:compileDebugJavaWithJavac'. Compilation failed; see the compiler error output for details. Information:BUILD FAILED Information:Total time: 6.231 secs Information:3 errors Information:0 warnings Information:See complete output in console
The getProduct()
error can be found in setPriceVisibility()
method.
According to me FragmentProductDetailsBinding mBinder
refers only to the standard layout, but there's no binder for the sw720dp layout. How do I solve this?
EDIT: I've added the following:
FragmentProductDetailsBindingSw720dpImpl mBinder720;
mBinder720 = DataBindingUtil.inflate(inflater, R.layout.fragment_product_details, container, false);
mBinder720.setProduct(mProduct);
mBinder720.getProduct().getNormalPrice().equals(mBinder720.getProduct().getSpecialPrice())
This way I have two binders and it works, but there must be a better way.
EDIT 2: I've posted the question at the Android bug tracker, please feel free to correct me if you have any suggestion.
For some reason the getter is not defined on the binding class
FragmentProductDetailsBinding
like it's documented:The
*Impl
classes extend this class and define this getter method while the setter is overridden. So I'd consider this to be a bug on the data binding generation side.In your case you could work around this by using
mProduct
from yourFragment
directly.