自定义可以自动计算的一行标题可左右滑动

本文介绍了一种自定义的TabLayout实现方法,该方法可根据标签数量自动调整布局,支持单行居中显示及多行左右滑动,并提供代码示例。

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

分类标签,一行展示,如果超过一行要可以左右滑动,不超过一行要平分布局居中展示。

初步使用 tablayout 来实现,自定义布局继承容器,添加layout布局是tablayout。根据数量大概判断设置tablayout模式。


点击每个item 下拉弹框展示一堆数据。感觉这样不太好,于是想着看能不能自己写一套出来。

初步想法,定义一个LinearLayout布局,每添加一个item进行长度计算,看是否超过一屏,超过一屏改换HorizontalScrollView。

每个item长度包括textview本身大小和margin左右距离。获取屏幕宽度。

我记得之前写搜索历史标签的时候计算过类似的,拿来用用,翻翻之前博客去!完了之前竟然没记录亏大了。

经过几个小时的研究终于完成了。

效果图

好了,终于成功了,点击弹框后面再想想加吧,这个支持超过一行滑动,自动的哦,不到一行默认均分!

上代码

package com.wavewave.popuwindow;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;

import java.util.List;

/**
 * @author wavewave
 * @CreateDate: 2020/10/22 3:23 PM
 * @Description: 类似TabLayout 没有下划线,视图自动适配居中,当超过一屏自动左右滑动
 * 可以自己设置默认间距
 * @Version: 1.0
 */
public class TitleFilterView extends HorizontalScrollView {

    private TitleLinearLayout mTitleLinearLayout;
    /**
     * 默认标签间距,当不超过屏幕会平均分
     */
    private int textViewMarginLeft = 10;
    /**
     * 默认高度
     */
    private int itemHeight = 88;

    public TitleFilterView(Context context) {
        this(context, null);
    }

    public TitleFilterView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, R.attr.tabStyle);
    }

    public TitleFilterView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TitleFilterView);
        textViewMarginLeft = typedArray.getInt(R.styleable.TitleFilterView_itemMargin, textViewMarginLeft);
        itemHeight = typedArray.getInt(R.styleable.TitleFilterView_titleHeight, itemHeight);
    }

    private void init() {
        mTitleLinearLayout = new TitleLinearLayout(getContext());
        mTitleLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
        super.addView(mTitleLinearLayout, 0,
                new HorizontalScrollView.LayoutParams(
                        LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));

    }

    @SuppressLint("NewApi")
    public void setData(List<String> list) {
        if (list == null || list.size() == 0) {
            return;
        }
        mTitleLinearLayout.removeAllViews();
        for (int i = 0; i < list.size(); i++) {
            LinearLayout linearLayout = new LinearLayout(getContext());
            linearLayout.setLayoutParams(new ViewGroup.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
            int[] attrs = new int[]{android.R.attr.selectableItemBackground};
            TypedArray ta = getContext().obtainStyledAttributes(attrs);
            Drawable mDefaultFocusHighlightCache = ta.getDrawable(0);
            ta.recycle();
            linearLayout.setForeground(mDefaultFocusHighlightCache);

            linearLayout.setGravity(Gravity.CENTER);
            ImageView imageView = new ImageView(getContext());
            imageView.setImageResource(R.mipmap.icon_up_down);
            imageView.setPadding(5, 0, 0, 0);
            final TextView mTextView = new TextView(getContext());
//            mTextView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
            mTextView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, itemHeight));
            mTextView.setTextColor(Color.BLACK);
            mTextView.setGravity(Gravity.CENTER);
            mTextView.setText(list.get(i));

            linearLayout.setPadding(textViewMarginLeft, 0, textViewMarginLeft, 0);
            linearLayout.addView(mTextView);
            linearLayout.addView(imageView);
            linearLayout.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {

                }
            });
            mTitleLinearLayout.addView(linearLayout);
        }
    }

    public class TitleLinearLayout extends LinearLayout {
        private int maxWidth;
        private int currentWidth = 0;
        private boolean isLine = true;

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

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int childCount = getChildCount();
            maxWidth = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
            if (childCount > 0) {
                currentWidth = 0;
                for (int i = 0; i < childCount; i++) {
                    Log.d("aaaaaa", "currentWidth::" + currentWidth);
                    View childAt = getChildAt(i);
                    measureChild(childAt, widthMeasureSpec, heightMeasureSpec);
                    if (maxWidth <= currentWidth + childAt.getMeasuredWidth()) {
                        isLine = false;
                        break;
                    } else {
                        isLine = true;
                        currentWidth += childAt.getMeasuredWidth();
                    }
                }
                Log.d("aaaaaa", "isLine::" + isLine);

            }
        }

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
            if (isLine) {//一行可以展示完毕
                int childCount = getChildCount();
                int addChildWidth = (maxWidth - currentWidth) / childCount;
                for (int i = 0; i < getChildCount(); i++) {
                    View childAt = getChildAt(i);
                    int paddingLeft = textViewMarginLeft + addChildWidth / 2;
                    int paddingTop = childAt.getPaddingTop();
                    int paddingRight = textViewMarginLeft + addChildWidth / 2;
                    int paddingBottom = childAt.getPaddingBottom();
                    Log.d("aaaaa", "paddingLeft:" + paddingLeft + "  paddingTop:" + paddingTop + "  paddingRight:" + paddingRight + "  paddingBottom:" + paddingBottom);
                    childAt.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
                }
                Log.d("aaaaaa", "onLayout isLine::" + isLine);
            } else {

            }
        }
    }
}

自定义了两个属性 可以不要

    <declare-styleable name="TitleFilterView">
        <attr name="titleHeight" format="integer" />
        <attr name="itemMargin" format="integer" />
    </declare-styleable>

搞定!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值