android解决视图超出屏幕范围显示问题
16lz
2021-01-23
发先一个ViewGroup超好用的属性。
android:clipChildren 是否裁剪子布局
<FrameLayout 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" tools:context="com.dqs.shangri.clipchildren.MainActivity" android:clipChildren="false"> <LinearLayout android:layout_width="match_parent" android:layout_height="20dp" android:layout_marginTop="200dp" android:background="@color/colorAccent" android:gravity="bottom"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" android:layout_gravity="center_vertical"/> <ImageView android:layout_width="30dp" android:layout_height="30dp" android:background="@color/colorPrimary"/> LinearLayout>FrameLayout>
效果图:
其中蓝色部分已经超出了父布局。
奇妙无比,可以完成许多设计想出的方案。。。。。。。。。。
为什么会发现这个东西呢。是因为最近做个自定义布局。会自动填充内容,长度不可预期,内容为一个textView,文案长度不固定。之后会做一个动画从屏幕右方票到屏幕左方。
一切都做好了,但是动画播出后,ViewGroup被裁剪了,只剩下屏幕宽度。所以才找出了这个属性。但是单凭这个属性还不够,还有另外一个步骤就是:自定义的这个布局要继承HorizontalScrollView。
- HorizontalScrollView 水平超出屏幕范围;
- ScrollView 当竖直超出屏幕范围。
android:clipChildren="false"
改属性一定写到跟布局。
下面是源码:
public class MosaicBgViewGroup extends HorizontalScrollView { private Logger logger = Logger.getLogger(getClass()); private AnimatorSet animatorSet; private RelativeLayout rootView; private View childView; private LinearLayout loadCarryingBgLy; private LinearLayout contentLy; private ImageView headerView; private ImageView tailView; private int headerViewResId; private int tailViewResId; private int middleViewResId; private int middleViewMarginLeft = DisplayUtil.dip2px(getContext(), 25); private int tailViewEffectiveSpace = DisplayUtil.dip2px(getContext(), 0.5f); public MosaicBgViewGroup(Context context) { super(context); } public MosaicBgViewGroup(Context context, AttributeSet attrs) { super(context, attrs); } public MosaicBgViewGroup(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void initResId(@DrawableRes int headerViewResId, @DrawableRes int tailViewResId, @DrawableRes int middleViewResId) { this.headerViewResId = headerViewResId; this.tailViewResId = tailViewResId; this.middleViewResId = middleViewResId; } public void setMiddleViewMarginLeft(int middleViewMarginLeft) { this.middleViewMarginLeft = middleViewMarginLeft; } public void setTailViewEffectiveSpace(int tailViewEffectiveSpace) { this.tailViewEffectiveSpace = tailViewEffectiveSpace; } public void addChildView(View view) { if (view == null || headerViewResId == 0 || tailViewResId == 0 || middleViewResId == 0) { logger.error("add child view is null!"); return; } removeAllViews(); rootView = new RelativeLayout(getContext()); childView = view; contentLy = new LinearLayout(getContext()); contentLy.setOrientation(LinearLayout.HORIZONTAL); initHeaderView(); initTailView(); initLoadCarryingBgLy(); rootView.addView(loadCarryingBgLy); contentLy.addView(headerView); contentLy.addView(childView); rootView.addView(contentLy); addView(rootView); } public void runAnim(AnimatorSet animatorSet) { if (animatorSet == null) { logger.error("run anim error, anim null!"); return; } this.animatorSet = animatorSet; this.animatorSet.start(); } private void initHeaderView() { headerView = new ImageView(getContext()); headerView.setScaleType(ImageView.ScaleType.CENTER); headerView.setImageResource(headerViewResId); } private void initTailView() { tailView = new ImageView(getContext()); tailView.setScaleType(ImageView.ScaleType.CENTER); tailView.setImageResource(tailViewResId); } private void initLoadCarryingBgLy() { loadCarryingBgLy = new LinearLayout(getContext()); loadCarryingBgLy.setPadding(middleViewMarginLeft, 0, 0, 0); loadCarryingBgLy.setOrientation(LinearLayout.HORIZONTAL); for (int i = 0; i < getMiddleCount(); i++) { ImageView view = new ImageView(getContext()); view.setScaleType(ImageView.ScaleType.CENTER); view.setBackgroundResource(middleViewResId); loadCarryingBgLy.addView(view); } loadCarryingBgLy.addView(tailView); } private int getChildViewWidth(View view) { int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); view.measure(spec,spec); return view.getMeasuredWidth(); } private int getMiddleCount() { int diff = ((getChildViewWidth(childView) % getMiddleWidth()) >= tailViewEffectiveSpace ? 1 : 0) + 1; return (getChildViewWidth(childView) / getMiddleWidth()) + diff; } private int getMiddleWidth() { View view = new View(getContext()); view.setBackgroundResource(middleViewResId); return getChildViewWidth(view); }}
更多相关文章
- Android中 将布局文件/View显示至手机屏幕的 整个过程分析
- 《转》Android 今日头条屏幕适配方案终极版正式发布!
- 如何动态获取Android系统属性
- Android Launcher分析和修改2——Icon修改、界面布局调整、壁纸
- Android:自适应不同分辨率的屏幕大小、方向和不同分辨率的字体大
- Android之在父视图上面布局子视图
- Android属性动画实战教程中篇
- Android 开发之旅:深入分析布局文件&又是“Hello World!”
- 4种Android屏幕自适应解决方案