CantThinkOfAnything
CantThinkOfAnything

Reputation: 1179

Layout height not updating properly after collapse and expand animation

Good morning peeps.

I am trying to create a dynamic layout on which you can add and delete tags. The layout also has to be collapsable and expandable.

Now everything works fine, the layouts height is updated properly with the adding and removing of the tags but the functionality stops after i perform a collapse and expand. I am not sure what the cause would be for this. If someone could point me in the right direction, id be very pleased!

the code:

public class FilterActivity extends AppCompatActivity {

    Logger logger = Logger.getLogger();

    LinearLayout tagsContainerLayout;

    Switch tagSwitch;

    // tag button
    ImageButton addTagButton;
    Button goButton;

    // heights for expanding
    Map<Integer, Integer> originalHeights;

    // tags
    ArrayList<String> selectedTags;

    // tag text bar
    AutoCompleteTextView tagsBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_filter);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        originalHeights = new HashMap<>();
        selectedTags = new ArrayList<>();

        // tag bar
        tagsBar = (AutoCompleteTextView) findViewById(R.id.tagSearch);

        // add tag
        addTagButton = (ImageButton) findViewById(R.id.addBtn);
        addTagButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String tag = tagsBar.getText().toString();

                if (!selectedTags.contains(tag)){
                    addTagToLayout(tag);
                }
            }
        });

        // start search
        goButton = (Button) findViewById(R.id.startSearchBtn);

        // switches
        tagSwitch = (Switch) findViewById(R.id.tagSwitch);

        tagSwitch.setChecked(true);

        tagLayout = (RelativeLayout) findViewById(R.id.tagsLayout);
        tagsContainerLayout = (LinearLayout) findViewById(R.id.tagContainer);

        // layouts
        addChecked(tagSwitch, tagLayout);
    }



    private void addTagToLayout(final String tagText)
    {
        // create tag
        final TextView newTag = new TextView(this);
        newTag.setText(tagText);

        newTag.setTextSize(getResources().getDimension(R.dimen.textsize));

        Drawable img = this.getResources().getDrawable(R.drawable.delete_tag_icon);
        newTag.setCompoundDrawablesWithIntrinsicBounds(img, null, null, null);
        logger.d(tagText);

        newTag.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));

        tagsContainerLayout.addView(newTag);

        logger.e("tag container height = " + tagsContainerLayout.getHeight());
        logger.e("tag top layout height = " + tagLayout.getHeight());

        ViewGroup.LayoutParams params = tagLayout.getLayoutParams();
        //params.height = newTag.getHeight() + tagLayout.getHeight();
        logger.e("new attempted height = " + String.valueOf(params.height + newTag.getHeight()));

        logger.e("params height = " + params.height);
        logger.e("newTag height = " + newTag.getHeight());

        //tagLayout.setLayoutParams(params);

        selectedTags.add(tagText);


        newTag.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tagsContainerLayout.removeView(newTag);
                tagsContainerLayout.invalidate();
                //tagsLayout.re
                selectedTags.remove(tagText);

            }
        });

        tagLayout.requestLayout();
        tagsContainerLayout.requestLayout();
    }

    public void addChecked(final Switch s, final View target)
    {
        s.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    expand(target);
                } else {
                    collapse(target);
                }
            }
        });
    }

    private void expand(View summary) {
        //set Visible
        summary.setVisibility(View.VISIBLE);

        //final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        final int height = originalHeights.get(summary.getId());

        //summary.measure(widthSpec, height);

        ValueAnimator mAnimator = slideAnimator(0, 400, summary);

        mAnimator.start();
    }

    private void saveOriginalHeight(int id, int height)
    {
        originalHeights.put(id, height);
    }

    private void collapse(final View summary) {
        int finalHeight = summary.getHeight();

        saveOriginalHeight(summary.getId(), finalHeight);

        ValueAnimator mAnimator = slideAnimator(finalHeight, 0, summary);

        mAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationEnd(Animator animator) {
                //Height=0, but it set visibility to GONE
                summary.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationStart(Animator animator) {
            }

            @Override
            public void onAnimationCancel(Animator animator) {
            }

            @Override
            public void onAnimationRepeat(Animator animator) {
            }
        });
        mAnimator.start();
    }


    private ValueAnimator slideAnimator(int start, int end, final View summary) {

        ValueAnimator animator = ValueAnimator.ofInt(start, end);

        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                //Update Height
                int value = (Integer) valueAnimator.getAnimatedValue();

                ViewGroup.LayoutParams layoutParams = summary.getLayoutParams();
                layoutParams.height = value;
                summary.setLayoutParams(layoutParams);
            }
        });
        return animator;
    }
}

As you can see I have been trying to do it manually but it doesnt work as newTag.getHeight() keeps returning 0 for some reason.

Upvotes: 1

Views: 373

Answers (1)

inKirby
inKirby

Reputation: 51

It's probably because you trying to get it's height before it's being rendered, try using measure, then getMeasuredHeight instead of getHeight on your newly created tag.

Upvotes: 1

Related Questions