title: How to programmatically reMeasure view?
body: <p>I have <code>CustomView</code> with 2 <code>RelativeLayouts</code>. There are <code>RecyclerViews</code> in each <code>RelativeLayout</code>. When I add new element to <code>RecyclerView</code> it doesn`t change height. </p>
  
  <p>If I change screen orientation then android measures it well. So my question is how to programmatically tell android that he needs remeasure both childs and parent elements.</p>
  
  <p><code>requestlayout()</code> and <code>invalidate()</code> doesn`t work</p>
  
  <p><strong>CustomView:</strong></p>
  
  <pre><code>public class ExpandableView extends LinearLayout {
  
  
      private Settings mSettings ;
      private int mExpandState;
      private ValueAnimator mExpandAnimator;
      private ValueAnimator mParentAnimator;
      private AnimatorSet mExpandScrollAnimatorSet;
      private  int mExpandedViewHeight;
      private  boolean mIsInit = true;
      private int defaultHeight;
  
      private boolean isAllowedExpand = false;
  
      private ScrolledParent mScrolledParent;
      private OnExpandListener mOnExpandListener;
  
  
      public ExpandableView(Context context) {
          super(context);
  
          init(null);
  
      }
  
      public ExpandableView(Context context, @Nullable AttributeSet attrs) {
          super(context, attrs);
          init(attrs);
  
      }
  
      public ExpandableView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
          super(context, attrs, defStyleAttr);
  
      }
  
      private void init(AttributeSet attrs) {
          Log.w("tag", "init");
          setOrientation(VERTICAL);
          this.setClipChildren(false);
          this.setClipToPadding(false);
  
          mExpandState = ExpandState.PRE_INIT;
          mSettings = new Settings();
          if(attrs!=null) {
              TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ExpandableView);
              mSettings.expandDuration = typedArray.getInt(R.styleable.ExpandableView_expDuration, Settings.EXPAND_DURATION);
              mSettings.expandWithParentScroll = typedArray.getBoolean(R.styleable.ExpandableView_expWithParentScroll,false);
              mSettings.expandScrollTogether = typedArray.getBoolean(R.styleable.ExpandableView_expExpandScrollTogether,true);
              typedArray.recycle();
          }
  
  
      }
  
      @Override
      public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
          super.onMeasure(widthMeasureSpec, heightMeasureSpec);
          Log.w("tag", "onMeasure");
          Log.w("tag", "widthMeasureSpec - " + widthMeasureSpec);
          Log.w("tag", "heightMeasureSpec - " + heightMeasureSpec);
          int childCount = getChildCount();
          if(childCount!=2) {
              throw new IllegalStateException("ExpandableLayout must has two child view !");
          }
          if(mIsInit) {
  
              ((MarginLayoutParams)getChildAt(0).getLayoutParams()).bottomMargin=0;
              MarginLayoutParams marginLayoutParams = ((MarginLayoutParams)getChildAt(1).getLayoutParams());
              marginLayoutParams.bottomMargin=0;
              marginLayoutParams.topMargin=0;
              marginLayoutParams.height = 0;
              mExpandedViewHeight = getChildAt(1).getMeasuredHeight();
              defaultHeight = mExpandedViewHeight;
  
              mIsInit =false;
              mExpandState = ExpandState.CLOSED;
              View view = getChildAt(0);
              if (view != null){
                  view.setOnClickListener(v -&gt; toggle());
              }
              super.onMeasure(widthMeasureSpec, heightMeasureSpec);
          }
      }
  
      @Override
      protected void onSizeChanged(int w, int h, int oldw, int oldh) {
          super.onSizeChanged(w, h, oldw, oldh);
          Log.w("tag", "onSizeChanged");
          if(mSettings.expandWithParentScroll) {
              mScrolledParent = Utils.getScrolledParent(this);
          }
      }
  
      private int getParentScrollDistance () {
          int distance = 0;
          Log.w("tag", "getParentScrollDistance");
          if(mScrolledParent == null) {
              return distance;
          }
          distance = (int) (getY() + getMeasuredHeight() + mExpandedViewHeight - mScrolledParent.scrolledView.getMeasuredHeight());
          for(int index = 0; index &lt; mScrolledParent.childBetweenParentCount; index++) {
              ViewGroup parent = (ViewGroup) getParent();
              distance+=parent.getY();
          }
  
          return distance;
      }
  
      private void verticalAnimate(final int startHeight, final int endHeight ) {
          int distance = getParentScrollDistance();  
  
          final View target = getChildAt(1);
  
          mExpandAnimator = ValueAnimator.ofInt(startHeight,endHeight);
          mExpandAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
              @Override
              public void onAnimationUpdate(ValueAnimator animation) {
                  target.getLayoutParams().height = (int) animation.getAnimatedValue();
                  target.requestLayout();
              }
          });
  
          mExpandAnimator.addListener(new AnimatorListenerAdapter() {
              @Override
              public void onAnimationEnd(Animator animation) {
                  super.onAnimationEnd(animation);
                  if(endHeight-startHeight &lt; 0) {
                      mExpandState = ExpandState.CLOSED;
                      if (mOnExpandListener != null) {
                          mOnExpandListener.onExpand(false);
                      }
                  } else {
                      mExpandState=ExpandState.EXPANDED;
                      if(mOnExpandListener != null) {
                          mOnExpandListener.onExpand(true);
                      }
                  }
              }
          });
  
  
          mExpandState=mExpandState==ExpandState.EXPANDED?ExpandState.CLOSING :ExpandState.EXPANDING;
  
          mExpandAnimator.setDuration(mSettings.expandDuration);
  
          if(mExpandState == ExpandState.EXPANDING &amp;&amp; mSettings.expandWithParentScroll &amp;&amp; distance &gt; 0) {
  
              mParentAnimator = Utils.createParentAnimator(mScrolledParent.scrolledView, distance, mSettings.expandDuration);
  
              mExpandScrollAnimatorSet = new AnimatorSet();
  
              if(mSettings.expandScrollTogether) {
                  mExpandScrollAnimatorSet.playTogether(mExpandAnimator,mParentAnimator);
              } else {
                  mExpandScrollAnimatorSet.playSequentially(mExpandAnimator,mParentAnimator);
              }
              mExpandScrollAnimatorSet.start();
  
          } else {
              mExpandAnimator.start();
          }
  
  
      }
  
      public void setExpand(boolean expand) {
          if (mExpandState == ExpandState.PRE_INIT) {return;}
  
          getChildAt(1).getLayoutParams().height = expand ? mExpandedViewHeight : 0;
          requestLayout();
          mExpandState=expand?ExpandState.EXPANDED:ExpandState.CLOSED;
      }
  
      public boolean isExpanded() {
          return mExpandState==ExpandState.EXPANDED;
      }
  
      public void toggle() {
          if (isAllowedExpand){
              if(mExpandState==ExpandState.EXPANDED) {
                  close();
              }else if(mExpandState==ExpandState.CLOSED) {
                  expand();
              }
          }
      }
  
      public void expand() {
          verticalAnimate(0,mExpandedViewHeight);
      }
  
      public void close() {
          verticalAnimate(mExpandedViewHeight,0);
      }
  
      public interface OnExpandListener {
          void onExpand(boolean expanded) ;
      }
  
      public void setOnExpandListener(OnExpandListener onExpandListener) {
          this.mOnExpandListener = onExpandListener;
      }
  
  
      public void setExpandScrollTogether(boolean expandScrollTogether) {
          this.mSettings.expandScrollTogether = expandScrollTogether;
      }
  
      public void setExpandWithParentScroll(boolean expandWithParentScroll) {
          this.mSettings.expandWithParentScroll = expandWithParentScroll;
      }
  
      public void setExpandDuration(int expandDuration) {
          this.mSettings.expandDuration = expandDuration;
      }
  
      @Override
      protected void onDetachedFromWindow() {
          super.onDetachedFromWindow();
          Log.w("tag", "onDetachedFromWindow");
          if(mExpandAnimator!=null&amp;&amp;mExpandAnimator.isRunning()) {
              mExpandAnimator.cancel();
              mExpandAnimator.removeAllUpdateListeners();
          }
          if(mParentAnimator!=null&amp;&amp;mParentAnimator.isRunning()) {
              mParentAnimator.cancel();
              mParentAnimator.removeAllUpdateListeners();
          }
          if(mExpandScrollAnimatorSet!=null) {
              mExpandScrollAnimatorSet.cancel();
          }
      }
  
      public void setAllowedExpand(boolean allowedExpand) {
          isAllowedExpand = allowedExpand;
      }
  
      public void increaseDistance(int size){
  
          if(mExpandState==ExpandState.EXPANDED) {
              close();
          }
  
          mExpandedViewHeight = defaultHeight + size;
  
      }
  
  
  //func just for loggs
      public void showParams(){
  
          RelativeLayout relativeLayout = (RelativeLayout) getChildAt(1);
          /*relativeLayout.requestLayout();
          relativeLayout.invalidate();*/
  
  
  
          RecyclerView recyclerView = (RecyclerView) relativeLayout.getChildAt(1);
  
          Log.d("tag", "height - " + relativeLayout.getHeight());
          Log.d("tag", "childs - " +  relativeLayout.getChildCount());
          Log.d("tag", "recycler height - " +   recyclerView.getHeight());
  
          recyclerView.requestLayout();
          recyclerView.invalidateItemDecorations();
          recyclerView.invalidate();
  
  
          RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
          layoutManager.getHeight();
  
  
  
          Log.d("tag", " layoutManager.getHeight() - " + layoutManager.getHeight());
          layoutManager.requestLayout();
          layoutManager.generateDefaultLayoutParams();
          layoutManager.onItemsChanged(recyclerView);
  
  
          Log.d("tag", " layoutManager.getHeight()2- " + layoutManager.getHeight());
  
  
          layoutManager.getChildCount();
          recyclerView.getChildCount();
          Log.d("tag", "manager childs - " + layoutManager.getChildCount());
          Log.d("tag", "recycler childs - " + recyclerView.getChildCount());
      }
  }
  </code></pre>
  
  <p><strong>Layout:</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:background="@color/grey_light_color"
      &gt;
  
  
      &lt;com.example.develop.project.Utils.ExpandableView.ExpandableView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:id="@+id/test_custom_view"
          app:expWithParentScroll="true"
          android:layout_gravity="center"
          android:background="@color/grey_color"
  
          &gt;
  
          &lt;android.support.v7.widget.CardView
              android:id="@+id/start_card"
              android:layout_width="match_parent"
              android:layout_height="70dp"
              android:background="@color/white_color"
              android:layout_marginTop="5dp"
              android:layout_marginStart="5dp"
              android:layout_marginEnd="5dp"
              &gt;
  
              &lt;RelativeLayout
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"&gt;
  
                  &lt;TextView
                      android:id="@+id/stage_tv4"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:textColor="@color/grey_deep_color"
                      android:text="Запуск"
                      android:layout_centerVertical="true"
                      android:layout_marginStart="15dp"
                      android:textSize="18sp"
  
                      /&gt;
  
  
  
              &lt;/RelativeLayout&gt;
  
          &lt;/android.support.v7.widget.CardView&gt;
  
          &lt;RelativeLayout
              android:layout_width="match_parent"
              android:layout_height="wrap_content"&gt;
  
              &lt;TextView
                  android:id="@+id/start_tv"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/start_accept"
                  android:textSize="18sp"
                  android:layout_marginStart="15dp"
                  android:layout_marginTop="15dp"
                  android:layout_marginBottom="15dp"
                  android:textColor="@color/grey_deep_color"
                  android:layout_marginEnd="15dp"
  
                  /&gt;
  
                  &lt;android.support.v7.widget.RecyclerView
                      android:id="@+id/my_test_tv"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:layout_below="@id/start_tv"
                      android:layout_marginTop="10dp"
                      android:layout_marginStart="15dp"
                      android:layout_marginEnd="15dp"
                      &gt;
  
                  &lt;/android.support.v7.widget.RecyclerView&gt;
  
          &lt;/RelativeLayout&gt;
  
  
  
      &lt;/com.example.develop.project.Utils.ExpandableView.ExpandableView&gt;
  
      &lt;Button
          android:id="@+id/add_btn"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentBottom="true"
          android:layout_alignParentStart="true"
          android:text="Add elem"
          android:layout_marginStart="15dp"
          android:layout_marginBottom="15dp"
          /&gt;
  
      &lt;Button
          android:id="@+id/check_btn"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentBottom="true"
          android:layout_alignParentEnd="true"
          android:text="Check params"
          android:layout_marginBottom="15dp"
          android:layout_marginEnd="15dp"
          /&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p><strong>Activity:</strong></p>
  
  <pre><code>public class TestActivity extends MvpAppCompatActivity implements TestContract.View {
  
  
      TestAdapter testAdapter;
  
      @InjectPresenter
      public TestPresenter presenter;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.test_layout);
  
          init();
      }
  
      private void init() {
          ExpandableView expandableView = findViewById(R.id.test_custom_view);
          expandableView.setAllowedExpand(true);
  
          Button add_btn = findViewById(R.id.add_btn);
          Button check_btn = findViewById(R.id.check_btn);
  
  
  
  
          add_btn.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
  
  
                  presenter.addElem();
  
              }
          });
  
          check_btn.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
  
                  expandableView.showParams();
              }
          });
      }
  
      @Override
      public void addElems(ArrayList&lt;String&gt; list) {
  
          testAdapter.notifyDataSetChanged();
  
      }
  
      @Override
      public void populateAdapter(ArrayList&lt;String&gt; list) {
  
          LinearLayoutManager layoutManager = new LinearLayoutManager(this);
  
          RecyclerView recyclerView = findViewById(R.id.my_test_tv);
          recyclerView.setLayoutManager(layoutManager);
          recyclerView.setNestedScrollingEnabled(false);
          recyclerView.setHasFixedSize(false);
  
  
  
          testAdapter = new TestAdapter(list);
          recyclerView.setAdapter(testAdapter);
      }
  }
  </code></pre>
  
  <p><strong>Adapter:</strong></p>
  
  <pre><code>public class TestAdapter extends RecyclerView.Adapter&lt;TestAdapter.TasksViewHolder&gt; {
      private List&lt;String&gt; list;
  
      public TestAdapter(List&lt;String&gt; list) {
          this.list = list;
  
  
      }
  
      @NonNull
      @Override
      public TestAdapter.TasksViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
          View v = LayoutInflater.from(parent.getContext())
                  .inflate(R.layout.test_item, parent, false);
  
          TestAdapter.TasksViewHolder vh = new TestAdapter.TasksViewHolder(v);
          return vh;
      }
  
      @Override
      public void onBindViewHolder(@NonNull TestAdapter.TasksViewHolder holder, int position) {
          String text = list.get(position);
  
  
          holder.textView.setText(text);
  
      }
  
  
      public static class TasksViewHolder extends RecyclerView.ViewHolder {
          private TextView textView;
  
  
          public TasksViewHolder(View itemView) {
              super(itemView);
              textView = itemView.findViewById(R.id.my_test_tv);
  
          }
  
  
      }
  
      @Override
      public int getItemCount() {
          return list.size();
      }
  }
  </code></pre>