FlowLayuot加上按钮

本文介绍了一种自定义的Android布局Flow Layout及其与Title View的结合使用方式。通过具体的代码示例,展示了如何创建可动态调整的布局,并实现与用户的交互功能,包括按钮点击事件的响应及布局内视图的添加与移除。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主xml

<?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="com.example.day_0609.MainActivity">
    <com.example.day_0609.TitleView
        android:id="@+id/titleView_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:left_text="-"
        app:right_text="+"
        app:title_text="首页"></com.example.day_0609.TitleView>
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/scrollView_main"
        >
        <com.example.day_0609.FlowLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/flowLayout_main"
            >
        </com.example.day_0609.FlowLayout>
    </ScrollView>

</LinearLayout>
 
attrs
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TopBar">
        <attr name="title_text" format="string"></attr>
        <attr name="title_text_size" format="dimension"></attr>
        <attr name="title_text_color" format="color"></attr>
        <attr name="title_bg_color" format="color"></attr>


        <attr name="left_btn_text" format="string"></attr>
        <attr name="left_btn_text_size" format="dimension"></attr>
        <attr name="left_btn_text_color" format="color"></attr>
        <attr name="left_btn_bg_color" format="reference"></attr>


        <attr name="right_btn_text" format="string"></attr>
        <attr name="right_btn_text_size" format="dimension"></attr>
        <attr name="right_btn_text_color" format="color"></attr>
        <attr name="right_btn_bg_color" format="reference"></attr>
    </declare-styleable>
</resources>

 
子布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:background="@color/colorPrimary"
    >
    <Button
        android:id="@+id/btn_left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:textSize="20dp"
        android:background="@color/colorAccent"
        />
    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:id="@+id/tv_title"
        android:layout_weight="1"
        android:layout_gravity="center"
        android:gravity="center"
        android:textSize="24dp"
        />
    <Button
        android:id="@+id/btn_right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:textSize="20dp"
        android:background="@color/colorAccent"
        />
</LinearLayout>


主 activity

public class MainActivity extends AppCompatActivity {
    private TitleView titleView;
    private FlowLayout flowLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化页面
        initViews();
    }


    private void initViews() {
        titleView = findViewById(R.id.titleView_main);
        flowLayout = findViewById(R.id.flowLayout_main);
        //设置监听
        titleView.setButtonOnClickListener(new TitleView.ButtonOnClickListener() {
            @Override
            public void leftOnClick() {
                //左按钮点击减少view
                flowLayout.removeViewAt(0);
            }

            @Override
            public void titleOnCLick() {
                //标题点击清除view
                flowLayout.removeAllViews();
            }

            @Override
            public void rightOnClick() {
                //右按钮点击添加view
                Button button = new Button(getApplicationContext());
                button.setText("杨运泽   宇宙无敌");
                button.setTextColor(Color.RED);
                //FlowLayout 继承的是ViewGroup,所以这里用ViewGroup
                ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT
                );
                //设置宽度为屏幕的一半
                params.width = getWindowManager().getDefaultDisplay().getWidth()/2;
                //设置高度为屏幕的1/5
                params.height = getWindowManager().getDefaultDisplay().getHeight()/25;
                //添加布局
                flowLayout.addView(button,params);
            }

        });
    }
}
 
FlowLayout



public class FlowLayout extends ViewGroup {
    public FlowLayout(Context context) {
        super(context);
    }

    public FlowLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //测量所有孩子的宽高
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heigghtMode = MeasureSpec.getMode(heightMeasureSpec);

        int width = 0;
        int height = 0;
        int lineWidth = 0;
        int lineHeight = 0;
        int totalHeight = 0;
        View childView;
        int childWidth = 0;
        int childHeight = 0;


        //遍历
        for (int i = 0; i < getChildCount(); i++) {
            //获得孩子组件
            childView = getChildAt(i);
            //获得孩子的宽高
            childWidth = childView.getMeasuredWidth();
            width = 2 * childWidth;
            childHeight = childView.getMeasuredHeight();
            //如果孩子宽太大
            if (childWidth > widthSize) {
                throw new IllegalArgumentException("子控件的宽度不能大于父控件的宽度");
            }
            //判断在左还是在右
            if (i % 2 == 0) {
                //累积的高添加
                totalHeight += lineHeight;
                lineHeight = childHeight;
                lineWidth = childWidth;
            } else {
                //累积的高添加
                totalHeight += lineHeight;
                //行宽累加
                lineWidth += childWidth;
                lineHeight = childHeight;
            }
            //如果是最后一个
            if (i == getChildCount() - 1) {
                totalHeight += lineHeight;
                height = totalHeight;
            }
        }

        //模式的判断
        width = widthMode == MeasureSpec.EXACTLY ? widthSize : width;
        height = heigghtMode == MeasureSpec.EXACTLY ? heightSize : height;
        //设置测量的宽高
        setMeasuredDimension(width,height);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int lineWidth = 0;
        int lineHeight = 0;
        int totalHeight = 0;
        View childView;
        int childWidth = 0;
        int childHeight = 0;
        //遍历
        for (int i = 0; i < getChildCount(); i++) {
            //获得孩子组件
            childView = getChildAt(i);
            //获得孩子的宽高
            childWidth = childView.getMeasuredWidth();
            childHeight = childView.getMeasuredHeight();
            //判断在左还是在右
            if (i % 2 == 0) {
                totalHeight += lineHeight;
                //模为0的都是第一个,所以行宽赋0
                lineWidth = 0;
                childViewLayout(childView,lineWidth,totalHeight,lineWidth+childWidth,totalHeight+childHeight);
                lineHeight = childHeight;
                lineWidth = childWidth;
            } else {

                totalHeight += lineHeight;
                //模为1的都是第二个 所以行宽为累加
                childViewLayout(childView,lineWidth,totalHeight,lineWidth+childWidth,totalHeight+childHeight);
                lineWidth += childWidth;
                lineHeight = childHeight;
            }
        }

    }

    public void childViewLayout(View childView,int l,int t,int r,int b){
        childView.layout(l,t,r,b);
    }
}
按钮
 


public class TitleView extends LinearLayout implements View.OnClickListener {
    private ButtonOnClickListener buttonOnClickListener;

    public TitleView(Context context) {
        super(context);
    }

    public TitleView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TitleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //加载属性
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.TitleView, 0, 0);
        String titleText = typedArray.getString(R.styleable.TitleView_title_text);
        String leftText = typedArray.getString(R.styleable.TitleView_left_text);
        String rightText = typedArray.getString(R.styleable.TitleView_right_text);

        //加载布局
        View inflate = inflate(context, R.layout.title_view_layout, this);
        TextView titleTv = inflate.findViewById(R.id.tv_title);
        Button leftBtn = inflate.findViewById(R.id.btn_left);
        Button rightBtn = inflate.findViewById(R.id.btn_right);
        //设置属性
        titleTv.setText(titleText);
        leftBtn.setText(leftText);
        rightBtn.setText(rightText);
        //设置点击事件
        leftBtn.setOnClickListener(this);
        titleTv.setOnClickListener(this);
        rightBtn.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_left:
                buttonOnClickListener.leftOnClick();
                break;
            case R.id.tv_title:
                buttonOnClickListener.titleOnCLick();
                break;
            case R.id.btn_right:
                buttonOnClickListener.rightOnClick();
                break;
            default:
                break;
        }
    }

    //接口回调
    public interface ButtonOnClickListener {
        void leftOnClick();

        void titleOnCLick();

        void rightOnClick();
    }

    //外部访问的方法
    public void setButtonOnClickListener(ButtonOnClickListener buttonOnClickListener) {
        this.buttonOnClickListener = buttonOnClickListener;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值