setMargins method is not working on custom ViewGro

2019-05-21 02:04发布

问题:

I am working on a project where my portion of work is to create a sliding layout on main screen which will partially appear at bottom when the app will start and we can scroll that layout. And then I have to add child views inside of it which will be cards. Now for that I have created a custom ViewGroup and I will add them programmatically.

I have succeed in making most of the portion of the task.

I have created a custom FrameLayout for sliding layout.

Then I used it and added in XML.

<?xml version="1.0" encoding="utf-8"?>
<com.dhrumil.airhockey.OverflowView
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@drawable/layer_list"
android:padding="5dp"
android:layout_height="match_parent"/>

Now after that I have created a java class named MyCardView which exends ViewGroup.

public class MyCardView extends ViewGroup {

    public MyCardView(Context context){
        super(context);
        init(context);
    }

    public MyCardView(Context context, AttributeSet attrs){
        super(context,attrs);
        init(context);
    }

    public MyCardView(Context context, AttributeSet attrs, int defStyleAttr){
        super(context, attrs,defStyleAttr);
        init(context);
    }

    public MyCardView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }

    public void init(Context context){

    }

    @Override
    protected void onLayout(boolean b, int l, int i1, int i2, int i3) {

        // TODO Auto-generated method stub
        final int count = getChildCount();
        int curWidth, curHeight, curLeft, curTop, maxHeight;

        //get the available size of child view
        int childLeft = this.getPaddingLeft();
        int childTop = this.getPaddingTop();
        int childRight = this.getMeasuredWidth() - this.getPaddingRight();
        int childBottom = this.getMeasuredHeight() - this.getPaddingBottom();
        int childWidth = childRight - childLeft;
        int childHeight = childBottom - childTop;

        maxHeight = 0;
        curLeft = childLeft;
        curTop = childTop;
        //walk through each child, and arrange it from left to right
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                //Get the maximum size of the child
                child.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST),
                        MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST));
                curWidth = child.getMeasuredWidth();
                curHeight = child.getMeasuredHeight();
                //wrap is reach to the end
                if (curLeft + curWidth >= childRight) {
                    curLeft = childLeft;
                    curTop += maxHeight;
                    maxHeight = 0;
                }
                //do the layout
                child.layout(curLeft, curTop, curLeft + curWidth, curTop + curHeight);
                //store the max height
                if (maxHeight < curHeight)
                    maxHeight = curHeight;
                curLeft += curWidth;
            }
        }

    }
}

Then I am trying to add objects of MyCardView into custom FrameLayout of mine programmatically.

Here is the method inside onCreate() which does the task. Which is to add two custom ViewGroups into one LinearLayout.

public void setupText(){
    FrameLayout frame = (FrameLayout) findViewById(R.id.overflow_frame);

    LinearLayout linearLayout = new LinearLayout(getBaseContext());
    linearLayout.setOrientation(LinearLayout.VERTICAL);

    ViewGroup vg = new MyCardView(getBaseContext());
    ViewGroup.MarginLayoutParams layoutParams = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,200);
    vg.setBackgroundColor(Color.WHITE);
    ViewCompat.setElevation(vg, 5);

    TextView tvTemp = new TextView(getBaseContext());
    tvTemp.setTextColor(Color.BLACK);
    tvTemp.setText("Hello There");

    vg.addView(tvTemp);

    ViewGroup vg1 = new MyCardView(getBaseContext());
    ViewGroup.MarginLayoutParams layoutParams1 = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,200);
    layoutParams1.setMargins(0,10,0,0);
    vg1.setBackgroundColor(Color.WHITE);
    ViewCompat.setElevation(vg1, 5);

    TextView tvTemp1 = new TextView(getBaseContext());
    tvTemp1.setTextColor(Color.BLACK);
    tvTemp1.setText("Hello There 2");

    vg1.addView(tvTemp1);

    linearLayout.addView(vg,layoutParams);
    linearLayout.addView(vg1,layoutParams1);

    frame.addView(linearLayout);
}

Now what happens is I am trying to set margin of ViewGroup but that doesn't seem to apply. Please Help.

回答1:

The mistake I was doing is, in my code I have declared an instance of ViewGroup.MarginLayoutParams layoutParams1 and I am passing the same instance in linearLayout.addView(vg1,layoutParams1) but the method addView() accepts View as first argument and an instance of LayoutParams as second.

So I think that was the problem (not fully sure). So I changed my code to

LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,200);