getHeight() doesn't get the height of the layout - android

I'm going to use dialog fragments.
There is an item called writing_comment_item.xml in the dialogfragment, and I want to set the height of 5 items.
I used the inflate() function, I used getHeight() to get the layout.
But as a result of debugging, the height is 0 no matter how much.
I tried in onCreate(). Also tried onCreateView() as well.
But the result was the same
What should I do?
writing_comment_item.xml
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".fragment.WritingCommentDialogFragment">
<EditText
android:id="#+id/comment_edit"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:gravity="center_vertical"
android:drawableLeft="#drawable/ic_bullet_point"
android:drawablePadding="5dp"
android:layout_marginHorizontal="10dp"
android:background="#null"
android:textSize="15sp"
android:inputType="text"
android:maxLines="1"
android:maxLength="22"
android:imeOptions="actionNext"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
</EditText>
</androidx.constraintlayout.widget.ConstraintLayout>
WCDialogFragment.java
public class WritingCommentDialogFragment extends DialogFragment implements CommentModel.EditInputListener {
OnBackPressedCallback callback;
LinearLayout commentContainer; // input layout
private final List<Comment> comments = new ArrayList<>();
private LayoutInflater layoutInflater;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_writing_comment_dialog, container, false);
bindViews(view);
addCommentItem();
return view;
}
private void bindViews(View v) {
commentContainer = v.findViewById(R.id.container);
layoutInflater = LayoutInflater.from(getContext());
}
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setCanceledOnTouchOutside(false);
return dialog;
}
#Override
public void onResume() {
super.onResume();
setDialogSize();
}
private void setDialogSize() {
View v = LayoutInflater.from(getContext()).inflate(R.layout.writing_comment_item, null, false);
int h = v.getHeight() * 5;
getDialog().getWindow().setLayout(1000, h);
}
}
EDITED
private void setDialogSize() {
View v = LayoutInflater.from(getContext()).inflate(R.layout.writing_comment_item, null, false);
v.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
v.getMeasuredHeight();
int h = v.getMeasuredHeight() * 5;
getDialog().getWindow().setLayout(1000, h);
}
ADDED PIC

The mistake here is trying to get the height of a view that hasn't been added to the layout hierarchy. When you call
inflate(R.layout.writing_comment_item, null, false);
with attachToRoot being false, you are specifying that you don't want it to be added to the hierarchy yet so the system never measures the view.
You could instead call View.measure(int, int) yourself and then use View.getMeasuredHeight(). This question covers that in a bit more detail - Measuring a view before rendering it

Related

Why is getMeasuredHeight() not returning the exact value?

I want to set the height of the dialog fragment by finding the height of the layout.
That's five heights in the view.
I couldn't get the height of the layout using getHeight().
I for this I used getMeasuredHeight(). (getHeight() only returned 0.)
But getMeasuredHeight() doesn't seem to return the exact value either.
I tried to set it to a height of 5 times this layout, but the actual height is
Less than 5 heights are set. (Please refer to the photo)
Why is it like this?
writing_comment_xml
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".fragment.WritingCommentDialogFragment">
<EditText
android:id="#+id/comment_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:gravity="center_vertical"
android:drawableLeft="#drawable/ic_bullet_point"
android:drawablePadding="5dp"
android:layout_marginHorizontal="10dp"
android:background="#null"
android:textSize="15sp"
android:inputType="text"
android:maxLines="1"
android:maxLength="22"
android:imeOptions="actionNext"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
</EditText>
</androidx.constraintlayout.widget.ConstraintLayout>
EDITED
DialogFragment.java
public class WritingCommentDialogFragment extends DialogFragment implements CommentModel.EditInputListener {
OnBackPressedCallback callback;
LinearLayout commentContainer; // input layout
private final List<Comment> comments = new ArrayList<>();
private LayoutInflater layoutInflater;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_writing_comment_dialog, container, false);
bindViews(view);
addCommentItem();
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setDialogSize();
}
private void bindViews(View v) {
commentContainer = v.findViewById(R.id.container);
layoutInflater = LayoutInflater.from(getContext());
}
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.setCanceledOnTouchOutside(false);
return dialog;
}
private void setDialogSize() {
View v = LayoutInflater.from(getContext()).inflate(R.layout.writing_comment_item, null, false);
new Handler().post(() -> {
int size = v.getHeight() * 5;
getDialog().getWindow().setLayout(1000, size);
});
}
}
ADDED
Layout Inspector
fragment_writing_comment_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".fragment.WritingCommentDialogFragment">
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I think the underlying issue is that the dialog will slip inside another ViewGroup called the decorView which has some padding that is shrinking the dialog. Here is a simplified version of your code that resizing the dialog's window appropriately so the dialog is the size you want. Comments in the code explain things a little more.
public class WritingCommentDialogFragment extends DialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setWindowSize();
View view = inflater.inflate(R.layout.fragment_writing_comment_dialog, container, false);
return view;
}
private void setWindowSize() {
int[] widthHeight = getDialogSize();
Window window = getDialog().getWindow();
// Our dialog will go inside the decorView which may have padding. So, the window has
// to be the width of our dialog plus the padding.
View decorView = window.getDecorView();
int horizontalPadding = decorView.getPaddingStart() + decorView.getPaddingEnd();
int verticalPadding = decorView.getPaddingTop() + decorView.getPaddingBottom();
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(window.getAttributes());
lp.width = widthHeight[0] + horizontalPadding;
lp.height = widthHeight[1] + verticalPadding;
window.setAttributes(lp);
}
private int[] getDialogSize() {
View v = LayoutInflater.from(getContext())
.inflate(R.layout.writing_comment_item,
(ConstraintLayout) getView(), // This is the parent.
false); // Don't attach the view to the parent.
// Measure one of the five child views to be added. The width is match_parent and the
// height is wrap_content.
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
int height = v.getMeasuredHeight();
return new int[]{DIALOG_WIDTH, height * 5};
}
private static final int DIALOG_WIDTH = 1000; // Maybe should be dp?
}

change id of elements in a reusable xml layout

i have an xml file that contains a reusable layout that i want to be added when the user clicks a button.
inputs.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/add"
android:textColor="#color/text_color_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/edittext"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/amount"
android:textColor="#color/text_color_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/btn"
app:layout_constraintStart_toEndOf="#+id/textview"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity=""
android:text="#string/category"
android:textColor="#color/text_color_blue"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This layout is loaded into a fragment budgetFragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.dashboard.fragments.BudgetFrag">
<LinearLayout
android:id="#+id/budget_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="17dp"
android:orientation="vertical">
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="10dp"
app:srcCompat="#android:drawable/ic_input_add"/>
</FrameLayout>
the elements get loaded as I need them to but only one problem, all the elements have the same id which comes from the last element loaded.
private BudgetViewModel mViewModel;
private LinearLayout layout = null;
private TextView textView;
private Button button;
private EditText editText;
private ViewGroup viewGroup;
private View viewer;
private LayoutInflater layoutInflater;
private static String TAG = "BudgetFrag :: ";
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bugdet_fragment, container, false);
viewGroup = container;
return v;
}
public int findUnusedId(LinearLayout layout) {
int fID = 0;
while (layout.findViewById(++fID) != null) ;
return fID;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = ViewModelProviders.of(this).get(BudgetViewModel.class);
// TODO: Use the ViewModel
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
FloatingActionButton add_elements = view.findViewById(R.id.floating);
layout = view.findViewById(R.id.budget_layout);
add_elements.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View view = getDialog(getActivity(), layout);
layout.addView(view);
}
});
}
public View getDialog(Context context, final LinearLayout layout) {
layoutInflater = LayoutInflater.from(getContext());
viewer = layoutInflater.inflate(R.layout.buget_input, viewGroup, false);
AlertDialog.Builder b = new AlertDialog.Builder(context);
b.setTitle("Select A Category");
String[] types = {"Food", "Entertainment"};
final String[] selected = {""};
b.setItems(types, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
textView = viewer.findViewById(R.id.textview);
switch (which) {
case 0:
textView.setText("Food");
break;
case 1:
textView.setText("Entertainment");
break;
}
editText = viewer.findViewById(R.id.edittext);
Log.d(TAG, "DialogInterface :: editText :: " + editText.getId());
editText.setId(findUnusedId(layout));
button = viewer.findViewById(R.id.btn);
button.setId(findUnusedId(layout));
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "setOnClickListener :: editText :: " + editText.getId());
if(!editText.getText().toString().trim().isEmpty()){
Toast.makeText(getContext(), "textView.getId()", Toast.LENGTH_LONG).show();
Log.d(TAG, "setOnClickListener :: "+ editText.getText().toString());
}
}
});
dialog.dismiss();
}
}).show();
return viewer;
}
the getDialog method is where the action happens.
All three elements have the same id as the last added input layout elements.
the question is how can i make each added input layout is unique to be able to get the edittext data? how do i change the ids dynamically as the elememnts are being added?
ps. the number of input layout that can be added is infinite.
This could be a tricky method to handle this problem. First create instance variable like
ArrayList<RootView> rootViews = new ArrayList(); Then we have to generate our own ID to each Root View and its corresponding child views and put it inside above rootViews list.
Look below :
LinearLayout linearLayout = findViewById(R.id.linear);
TextView textView = linearLayout.findViewById(R.id.tv);
EditText editText = linearLayout.findViewById(R.id.et);
Button button = linearLayout.findViewById(R.id.btn);
int uniqueLinearLayoutId = View.generateViewId();
int uniqueTextViewId = View.generateViewId();
int uniqueFirstEditTextId = View.generateViewId();
int uniqueBtnId = View.generateViewId();
ArrayList<Integer> childViews = new ArrayList<>();
childViews.add(uniqueTextViewId);
childViews.add(uniqueFirstEditTextId);
childViews.add(uniqueBtnId);
rootViews.add(new RootView(uniqueLinearLayoutId,childViews));
Now we have structured our view id's inside rootViews list. So, now we can identify each view as they have unique id's.

Shared element back transition not working with recyclerview and cardviews in fragments

I'm trying to create a transition between a recycler view with cardviews fragment to a fragment that only contains 1 card. The problem is that the back transition is not working, while the enter transition is. If I remove setReorderingAllowed(true); then the back transition is working, but the enter transition stops working.
This is what I have.
Fragment with recyclerview with cardviews
public class OrdersFragment extends Fragment implements OrderAdapter.OnOrderListener {
private OrderAdapter mAdapter;
private TextView bonnenTextView;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
postponeEnterTransition();
}
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_bonnen, container, false);
bonnenTextView = view.findViewById(R.id.bonnen_text_view);
RecyclerView orderRecyclerView = view.findViewById(R.id.order_recycler_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
orderRecyclerView.setLayoutManager(layoutManager);
if (mAdapter == null) {
mAdapter = new OrderAdapter(this);
fetchOrders();
}
orderRecyclerView.setAdapter(mAdapter);
return view;
}
private void fetchOrders() {
new OrderFetcher().fetch(new Callback() {
#Override
public void onComplete(Result result) {
if (result instanceof Result.Success) {
mAdapter.setOrders((Order[]) ((Result.Success<?>)result).data);
mAdapter.notifyDataSetChanged();
} else {
Toast.makeText(getContext(), "Could not load orders", Toast.LENGTH_SHORT).show();
}
startPostponedEnterTransition();
}
});
}
#Override
public void onOrderClick(int position, View view, Order order) {
Log.i("OrderClick", "Transition name " + view.getTransitionName());
View carrierTextView = view.findViewById(R.id.carrier_text_view);
View numberTextView = view.findViewById(R.id.id_text_view);
View pickerTextView = view.findViewById(R.id.picker_text_view);
View locationTextView = view.findViewById(R.id.location_text_view);
FragmentTransaction transaction = getParentFragmentManager().beginTransaction();
transaction.addSharedElement(view, view.getTransitionName());
transaction.addSharedElement(carrierTextView, carrierTextView.getTransitionName());
transaction.addSharedElement(numberTextView, numberTextView.getTransitionName());
transaction.addSharedElement(pickerTextView, pickerTextView.getTransitionName());
transaction.addSharedElement(locationTextView, locationTextView.getTransitionName());
transaction.addSharedElement(bonnenTextView, bonnenTextView.getTransitionName());
transaction.replace(R.id.nav_host_fragment, BonFragment.newInstance(view.getTransitionName(), order));
transaction.addToBackStack(null);
transaction.setReorderingAllowed(true);
transaction.commit();
}
}
xml that goes with fragment above
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.orders.OrdersFragment">
<TextView
android:id="#+id/bonnen_text_view"
android:transitionName="bonnen_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:text="#string/orders"
android:textColor="#color/secondary"
android:textSize="40sp"
android:textStyle="bold"
android:typeface="normal" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/order_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"/>
</LinearLayout>
Fragment with single cardview
public static BonFragment newInstance(String cardTransitionName, Order order) {
BonFragment bonFragment = new BonFragment();
Bundle args = new Bundle();
args.putParcelable("orderParcel", order);
args.putString("cardTransitionName", cardTransitionName);
bonFragment.setArguments(args);
return bonFragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View root = inflater.inflate(R.layout.fragment_bon, container, false);
CardView orderCard = root.findViewById(R.id.order_card);
TextView carrierTextView = root.findViewById(R.id.carrier_text_view);
TextView numberTextView = root.findViewById(R.id.id_text_view);
TextView pickerTextView = root.findViewById(R.id.picker_text_view);
TextView locationTextView = root.findViewById(R.id.location_text_view);
if (getArguments() != null && getArguments().getParcelable("orderParcel") != null) {
Order order = getArguments().getParcelable("orderParcel");
orderCard.setTransitionName(getArguments().getString("cardTransitionName"));
if (order != null) {
carrierTextView.setTransitionName("carrier" + order.getIndex());
carrierTextView.setText(order.getCarrier());
numberTextView.setTransitionName("number" + order.getIndex());
numberTextView.setText(String.valueOf(order.getNumber()));
pickerTextView.setTransitionName("picker" + order.getIndex());
pickerTextView.setText(order.getPicker());
locationTextView.setTransitionName("location" + order.getIndex());
locationTextView.setText(order.getPosition());
carrierTextView.setText("Lorem Ipsum");
numberTextView.setText("Dolor sit amet");
pickerTextView.setText("consectetur adipiscing elit");
locationTextView.setText("Mauris semper");
}
}
orderCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getParentFragmentManager().popBackStack();
}
});
Transition transition = TransitionInflater.from(getContext()).inflateTransition(R.transition.card_transition);
setSharedElementEnterTransition(transition);
setSharedElementReturnTransition(transition);
return root;
}
xml that goes with fragment above
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.orders.OrdersFragment">
<TextView
android:transitionName="bonnen_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:text="#string/orders"
android:textColor="#color/secondary"
android:textSize="40sp"
android:textStyle="bold"
android:typeface="normal" />
<androidx.cardview.widget.CardView
android:id="#+id/order_card"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardBackgroundColor="#color/primaryLight"
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
android:layout_margin="25dp">
<LinearLayout
android:transitionName="order_card_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="10dp">
<TextView
android:id="#+id/carrier_text_view"
android:transitionName="carrier_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/secondary"
android:textSize="20sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/id_text_view"
android:transitionName="id_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/secondary" />
<TextView
android:id="#+id/picker_text_view"
android:transitionName="picker_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/secondary" />
<TextView
android:id="#+id/location_text_view"
android:transitionName="location_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/secondary" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
This is what it looks like with setReorderingAllowed(true);
This is what it looks like without setReorderingAllowed(true);
EDIT
After applying the answer given by ianhanniballake I got it working.
Here is what I did for future reference.
The only changes I made is in the OrdersFragment class.
I removed the override of the onCreate() method.
I removed the startPostponedEnterTransition(); from my fetchOrders() method and I added
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
postponeEnterTransition();
final ViewGroup parentView = (ViewGroup) view.getParent();
parentView.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
parentView.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
super.onViewCreated(view, savedInstanceState);
}
That's it
As per the Use shared element transitions with a RecyclerView guide, you're calling startPostponedEnterTransition() too early - after setting your data (and calling notifyDataSetChanged() to inform the adapter), you need to wait until the RecyclerView is actually measured and laid out. This requires that you add an OnPreDrawListener and only call startPostponedEnterTransition() once that fires.
In Kotlin you need to start the transition in doOnPreDraw callback of the recyclerView like below:
recyclerView.doOnPreDraw {
startPostponedEnterTransition()
}

Hide TextView on small screen

I'm trying to hide two TextViews on screens which have a smaller width than 500px.
I tried the following (this is not my complete code, but essential):
public class HeaderFooterFragment extends Fragment {
private TextView lable;
private TextView app;
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
lable = (TextView) fragmentView.findViewById(R.id.lable);
app = (TextView) fragmentView.findViewById(R.id.app);
// some code...
super.onActivityCreated(savedInstanceState);
}
public void setLableInvisible()
{
lable.setVisibility(View.INVISIBLE);
app.setVisibility(View.INVISIBLE);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Inflate the layout for this fragment
fragmentView = inflater.inflate(R.layout.fragment_header_footer, container, false);
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
int screenWidth = dm.widthPixels;
if(screenWidth < 500){
setLableInvisible();
}
return fragmentView;
}
}
My XML is:
<TextView
android:layout_width="wrap_content"
android:layout_height="#dimen/toolbar_height"
android:id="#+id/lable"
android:layout_weight="0.3"
android:textAlignment="gravity"
android:gravity="left"
android:text="#string/app_name"
android:textSize="#dimen/site_fontsize"
android:paddingTop="#dimen/site_paddingtop"
android:paddingLeft="#dimen/site_paddingleft"
android:textColor="#color/site_color"
android:scaleType="fitCenter"
android:visibility="visible"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="#dimen/toolbar_height"
android:layout_weight="0.05"
android:id="#+id/app"
android:textAlignment="gravity"
android:gravity="left"
android:text="#string/app_name_extra"
android:textSize="#dimen/apptitlex_fontsize"
android:paddingTop="#dimen/apptitlex_paddingtop"
android:paddingLeft="#dimen/apptitlex_paddingleft"
android:textColor="#color/colorAccent"
android:textAllCaps="true"
android:layout_alignParentRight="true"
android:scaleType="fitCenter"
android:visibility="visible"
/>
When I start the app on a Smartphone with width 480px, I get a null object reference. If i start the app on a much more bigger screen, the app isn't crashing.
Thanks in advance.
Im' not sure that the view is created yet in OnActivityCreated, Try initialize your textView in OnCreateView
lable = (TextView) fragmentView.findViewById(R.id.lable);
app = (TextView) fragmentView.findViewById(R.id.app);
try this and delete onactivitycreated method
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Inflate the layout for this fragment
fragmentView = inflater.inflate(R.layout.fragment_header_footer, container, false);
lable = (TextView) fragmentView.findViewById(R.id.lable);
app = (TextView) fragmentView.findViewById(R.id.app);
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
int screenWidth = dm.widthPixels;
if(screenWidth < 500){
setLableInvisible();
}
return fragmentView;
}
Declare TextView onCreateView instead of onActivityCreated section
View RootView; //Declare Global
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
RootView = inflater.inflate(R.layout.fragment_header_footer, container, false);
lable = (TextView) RootView.findViewById(R.id.lable);
app = (TextView) RootView.findViewById(R.id.app);
// Add Your staff here
return RootView;
}
Instead of this
setLableInvisible();
Use below code to hide textview
app.setVisibility(View.INVISIBLE)
Similarly user it for second textview.
Thanks

dynamic resize fragment android

I want to change the width of a fragment I'm using in my MaiActivity? But I can't find its LayoutParams for changing its default width:
public class MainActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
int widthFfragment = 300;
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
widthTot = size.x;
heightTot = size.y;
findViewById(R.id.f1).getLayoutParams().width = widthTot-widthFfragment;
}
}
This is my fragment's code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/f1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#330000"
android:gravity="center_horizontal|center_vertical"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment 1"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
Fragment1.java
public class Fragment1 extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//---Inflate the layout for this fragment---
return inflater.inflate( R.layout.fragment1, container, false);
}
}
Many thanks.
You can do it by working with the LayoutParams instance of the View obtained from Fragment.getView(). My sample code:
private void resizeFragment(Fragment f, int newWidth, int newHeight) {
if (f != null) {
View view = f.getView();
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(newWidth, newHeight);
view.setLayoutParams(p);
view.requestLayout();
}
}
And may be used as follows:
resizeFragment(myFragment, 200, 500);
resizeFragment(otherFragment, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
Your right, the Fragment does not have LayoutParams because it is a conceptual container, you either need to adjust the layout params of the inflated view in the fragment, or to the container you attach the fragment to.
public class Fragment1 extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup view = (ViewGroup) inflater.inflate( R.layout.fragment1, container, false);
// TODO Adjust layout params of inflated view here
return view;
}
The example assumes you are inflating a ViewGroup.
Hope that helps.

Categories

Resources