日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

自定义控件:流式布局

發(fā)布時(shí)間:2025/4/16 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自定义控件:流式布局 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

實(shí)現(xiàn)代碼

public class FlowLayout extends ViewGroup {private List<Line> mLines = new ArrayList<Line>(); // 用來(lái)記錄描述有多少行Viewprivate Line mCurrrenLine; // 用來(lái)記錄當(dāng)前已經(jīng)添加到了哪一行private int mHorizontalSpace = 10;private int mVerticalSpace = 10;public FlowLayout(Context context, AttributeSet attrs) {super(context, attrs);}public FlowLayout(Context context) {super(context);}public void setSpace(int horizontalSpace, int verticalSpace) {this.mHorizontalSpace = horizontalSpace;this.mVerticalSpace = verticalSpace;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// 清空mLines.clear();mCurrrenLine = null;int layoutWidth = MeasureSpec.getSize(widthMeasureSpec);// 獲取行最大的寬度int maxLineWidth = layoutWidth - getPaddingLeft() - getPaddingRight();// 測(cè)量孩子int count = getChildCount();for (int i = 0; i < count; i++) {View view = getChildAt(i);// 如果孩子不可見(jiàn)if (view.getVisibility() == View.GONE) {continue;}// 測(cè)量孩子measureChild(view, widthMeasureSpec, heightMeasureSpec);// 往lines添加孩子if (mCurrrenLine == null) {// 說(shuō)明還沒(méi)有開(kāi)始添加孩子mCurrrenLine = new Line(maxLineWidth, mHorizontalSpace);// 添加到 Lines中mLines.add(mCurrrenLine);// 行中一個(gè)孩子都沒(méi)有mCurrrenLine.addView(view);} else {// 行不為空,行中有孩子了boolean canAdd = mCurrrenLine.canAdd(view);if (canAdd) {// 可以添加mCurrrenLine.addView(view);} else {// 不可以添加,裝不下去// 換行// 新建行mCurrrenLine = new Line(maxLineWidth, mHorizontalSpace);// 添加到lines中mLines.add(mCurrrenLine);// 將view添加到linemCurrrenLine.addView(view);}}}// 設(shè)置自己的寬度和高度int measuredWidth = layoutWidth;// paddingTop + paddingBottom + 所有的行間距 + 所有的行的高度float allHeight = 0;for (int i = 0; i < mLines.size(); i++) {float mHeigth = mLines.get(i).mHeigth;// 加行高allHeight += mHeigth;// 加間距if (i != 0) {allHeight += mVerticalSpace;}}int measuredHeight = (int) (allHeight + getPaddingTop() + getPaddingBottom() + 0.5f);setMeasuredDimension(measuredWidth, measuredHeight);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {// 給Child 布局---> 給Line布局int paddingLeft = getPaddingLeft();int offsetTop = getPaddingTop();for (int i = 0; i < mLines.size(); i++) {Line line = mLines.get(i);// 給行布局line.layout(paddingLeft, offsetTop);offsetTop += line.mHeigth + mVerticalSpace;}}class Line {private List<View> mViews = new ArrayList<View>(); // 用來(lái)記錄每一行有幾個(gè)Viewprivate float mMaxWidth; // 行最大的寬度private float mUsedWidth; // 已經(jīng)使用了多少寬度private float mHeigth; // 行的高度private float mMarginLeft;private float mMarginRight;private float mMarginTop;private float mMarginBottom;private float mHorizontalSpace; // View和view之間的水平間距public Line(int maxWidth, int horizontalSpace) {this.mMaxWidth = maxWidth;this.mHorizontalSpace = horizontalSpace;}/*** 添加view,記錄屬性的變化* @param view*/public void addView(View view) {// 加載View的方法int size = mViews.size();int viewWidth = view.getMeasuredWidth();int viewHeight = view.getMeasuredHeight();// 計(jì)算寬和高if (size == 0) {// 說(shuō)還沒(méi)有添加Viewif (viewWidth > mMaxWidth) {mUsedWidth = mMaxWidth;} else {mUsedWidth = viewWidth;}mHeigth = viewHeight;} else {// 多個(gè)view的情況mUsedWidth += viewWidth + mHorizontalSpace;mHeigth = mHeigth < viewHeight ? viewHeight : mHeigth;}// 將View記錄到集合中mViews.add(view);}/*** 用來(lái)判斷是否可以將View添加到line中* @param view* @return*/public boolean canAdd(View view) {// 判斷是否能添加Viewint size = mViews.size();if (size == 0) {return true;}int viewWidth = view.getMeasuredWidth();// 預(yù)計(jì)使用的寬度float planWidth = mUsedWidth + mHorizontalSpace + viewWidth;if (planWidth > mMaxWidth) {// 加不進(jìn)去return false;}return true;}/*** 給孩子布局* @param offsetLeft* @param offsetTop*/public void layout(int offsetLeft, int offsetTop) {// 給孩子布局int currentLeft = offsetLeft;int size = mViews.size();// 判斷已經(jīng)使用的寬度是否小于最大的寬度float extra = 0;float widthAvg = 0;if (mMaxWidth > mUsedWidth) {extra = mMaxWidth - mUsedWidth;widthAvg = extra / size;}for (int i = 0; i < size; i++) {View view = mViews.get(i);int viewWidth = view.getMeasuredWidth();int viewHeight = view.getMeasuredHeight();// 判斷是否有富余if (widthAvg != 0) {// 改變寬度,View的長(zhǎng)度改變了,需要重新measureint newWidth = (int) (viewWidth + widthAvg + 0.5f);int widthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY);int heightMeasureSpec = MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY);view.measure(widthMeasureSpec, heightMeasureSpec);viewWidth = view.getMeasuredWidth();viewHeight = view.getMeasuredHeight();}// 布局int left = currentLeft;int top = (int) (offsetTop + (mHeigth - viewHeight) / 2 + 0.5f);// int top = offsetTop;int right = left + viewWidth;int bottom = top + viewHeight;view.layout(left, top, right, bottom);currentLeft += viewWidth + mHorizontalSpace;}}}} public class FlowActivity extends AppCompatActivity {private ScrollView mScrollView;private FlowLayout mFlowLayout;private List<String> mData;private Gson mGson;private String appname = "['QQ','視頻','京東','youni有你','萬(wàn)年歷-農(nóng)歷黃歷','支付寶錢(qián)包']";@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);initData();initView();}private void initData() {mGson = new Gson();mData = mGson.fromJson(appname,new TypeToken<List<String>>(){}.getType());}private void initView() {setContentView(mScrollView = new ScrollView(this));SpannableString title = new SpannableString("流式布局,熱門(mén)標(biāo)簽");title.setSpan(new ForegroundColorSpan(Color.WHITE),0,title.length(),Spannable.SPAN_INCLUSIVE_EXCLUSIVE);ActionBar actionBar = getSupportActionBar();actionBar.setTitle(title);mScrollView.setBackgroundColor(Color.parseColor("#eaeaea"));mScrollView.setVerticalScrollBarEnabled(false);mFlowLayout = new FlowLayout(this);int padding = UIUtil.dip2px(15);mFlowLayout.setPadding(UIUtil.dip2px(10), padding, UIUtil.dip2px(10), padding);mFlowLayout.setSpace(UIUtil.dip2px(10), UIUtil.dip2px(15));for (final String data : mData) {TextView textView = new TextView(this);int tvPadding = UIUtil.dip2px(10);textView.setPadding(UIUtil.dip2px(15), tvPadding, UIUtil.dip2px(15), tvPadding);textView.setGravity(Gravity.CENTER);textView.setTextSize(16);textView.setText(data);textView.setTextColor(Color.WHITE);Random random = new Random();//Math.random()int alpha = 255;int green = random.nextInt(190) + 30;int red = random.nextInt(190) + 30;int blue = random.nextInt(190) + 30;int argb = Color.argb(alpha, red, green, blue);//設(shè)置shapeGradientDrawable normalDrawable = new GradientDrawable();normalDrawable.setCornerRadius(UIUtil.dip2px(6));normalDrawable.setColor(argb);GradientDrawable pressedDrawable = new GradientDrawable();pressedDrawable.setColor(Color.DKGRAY);pressedDrawable.setCornerRadius(UIUtil.dip2px(5));//設(shè)置選擇器selectorStateListDrawable stateListDrawable = new StateListDrawable();stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, pressedDrawable);stateListDrawable.addState(new int[]{}, normalDrawable);textView.setBackgroundDrawable(stateListDrawable);textView.setClickable(true);textView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {ToastUtil.toast(data);}});mFlowLayout.addView(textView);}mScrollView.addView(mFlowLayout);} }

總結(jié)

以上是生活随笔為你收集整理的自定义控件:流式布局的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。