首页 文章 精选 留言 我的

精选列表

搜索[主题渐变],共10000篇文章
优秀的个人博客,低调大师

android 动态渐变 字符效果

public class GradientView extends View { private String TAG = " GradientView " ; private Handler mTimeTickHandler; private int mIndex = 190 ; private Shader mShader; private Bitmap mBitmapBg; private Bitmap mBitmapWord; private int mMinWidth = 190 ; private int mMaxWidth ; private int mUpdateStep = 20 ; private Paint mPaint = new Paint(); public GradientView(Context context) { super (context); } public GradientView(Context context, AttributeSet attrs) { super (context, attrs); mTimeTickHandler = new Handler(); setFocusable( true ); InputStream is = context.getResources().openRawResource(R.drawable.sliding_channel_background); mBitmapBg = BitmapFactory.decodeStream(is); mMaxWidth = mBitmapBg.getWidth(); mBitmapWord = Bitmap.createBitmap(mBitmapBg.getWidth(), mBitmapBg.getHeight(), Bitmap.Config.ALPHA_8); drawIntoBitmap(mBitmapWord, context); mTimeTickHandler.post(mTimeTickRunnable); } private void drawIntoBitmap(Bitmap bm, Context context) { float x = bm.getWidth(); float y = bm.getHeight(); Canvas c = new Canvas(bm); Paint p = new Paint(); p.setAntiAlias( true ); p.setColor(Color.WHITE); p.setTextSize( 45 ); p.setTextAlign(Paint.Align.CENTER); c.drawText(context.getResources().getString(R.string.slide_unlock), x / 2 + 10 , y / 2 , p); } @Override protected void onDraw(Canvas canvas) { // canvas.drawBitmap(mBitmapBg, 0, 0, p); mPaint.setShader(mShader); canvas.drawBitmap(mBitmapWord, 50 , 13 , mPaint); } public void removeHandlerGradient(){ mTimeTickHandler.removeCallbacks(mTimeTickRunnable); } private Runnable mTimeTickRunnable = new Runnable(){ public void run() { mIndex += mUpdateStep; if (mIndex >= mMaxWidth){ mIndex = mMinWidth; } mShader = new LinearGradient( 0 , 150 , mIndex, 150 , new int [] { Color.GRAY,Color.GRAY,Color.GRAY, Color.GRAY, Color.WHITE }, null , Shader.TileMode.MIRROR); postInvalidate(); mTimeTickHandler.postDelayed(mTimeTickRunnable, 100 ); } }; } 本文转自wanqi博客园博客,原文链接: http://www.cnblogs.com/wanqieddy/archive/2011/07/11/2103301.html 如需转载请自行联系原作者

优秀的个人博客,低调大师

Android -- ViewPager滑动背景渐变

原理 总布局为RelativeLayout或者FrameLayout,在这里我们用的是RelativeLayout。先设置背景图片,宽度和高度都fill_parent,在设置viewpager,viewpager的背景要透明哟~这样背景图片就可以显示在页面上。对viewpager进行滑动监听,通过滑动的偏移量对当前背景进行淡出,下一个背景进行显示。 布局 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MyActivity"> <us.yydcdut.viewpagercolorchange.BackGroundImage android:id="@+id/img" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </RelativeLayout> 有个自定义View,淡出等操作就是在自定义view中进行的。 Code public class MyActivity extends Activity { private BackGroundImage mImg; private ViewPager mViewPager; private List<View> mViewLists; private List<Drawable> mDrawableLists; private static final int ALL = 5; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); initViews(); mImg.setmDrawableLists(mDrawableLists); mViewPager.setAdapter(new MyAdapter()); mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int i, float v, int i2) { mImg.setmDegree(v); mImg.setmPosition(i); mImg.invalidate();//刷新 } @Override public void onPageSelected(int i) { } @Override public void onPageScrollStateChanged(int i) { } }); } private void initViews() { mImg = (BackGroundImage) findViewById(R.id.img); mViewPager = (ViewPager) findViewById(R.id.viewPager); mViewLists = new ArrayList<View>(); mDrawableLists = new ArrayList<Drawable>(); for (int i = 0; i < ALL; i++) { View view = getLayoutInflater().inflate(R.layout.vp, null); mViewLists.add(view); if (i % 2 == 0) { mDrawableLists.add(getResources().getDrawable(R.drawable.bg_img1)); } else { mDrawableLists.add(getResources().getDrawable(R.drawable.bg_img2)); } } } class MyAdapter extends PagerAdapter { @Override public int getCount() { return mViewLists.size(); } @Override public boolean isViewFromObject(View view, Object o) { return view == o; } @Override public void destroyItem(ViewGroup container, int position, Object object) { ((ViewPager) container).removeView(mViewLists.get(position)); //super.destroyItem(container, position, object); } @Override public Object instantiateItem(ViewGroup container, int position) { View v = mViewLists.get(position); TextView textView = (TextView) v.findViewById(R.id.txt); textView.setText("第" + position + "个"); ((ViewPager) container).addView(v); return v; } } } public class BackGroundImage extends View { private int mPosition; private float mDegree; private List<Drawable> mDrawableLists; private int mPrePosition = 0; private Drawable mNext; public void setmDrawableLists(List<Drawable> mDrawableLists) { this.mDrawableLists = mDrawableLists; mNext = mDrawableLists.get(1);//设置下一个背景图片的drawable } public void setmPosition(int mPosition) { this.mPosition = mPosition; } public void setmDegree(float mDegree) { this.mDegree = mDegree; } public BackGroundImage(Context context) { super(context); //setWillNotDraw(false); } public BackGroundImage(Context context, AttributeSet attrs) { super(context, attrs); //setWillNotDraw(false); } public BackGroundImage(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //setWillNotDraw(false); } @Override protected void onDraw(Canvas canvas) { Log.i("111", "onDraw"); if (null == mDrawableLists) { return; } int alpha1 = (int) (255 - (mDegree * 255)); Drawable fore = mDrawableLists.get(mPosition); fore.setBounds(0, 0, getWidth(), getHeight()); mNext.setBounds(0, 0, getWidth(), getHeight()); if (mPrePosition != mPosition) {//边界判断 if (mPosition != mDrawableLists.size() - 1) { mNext = mDrawableLists.get(mPosition + 1); } else { mNext = mDrawableLists.get(mPosition); } } fore.setAlpha(alpha1);//淡出 mNext.setAlpha(255); mNext.draw(canvas); fore.draw(canvas); mPrePosition = mPosition; super.onDraw(canvas); } } 我是天王盖地虎的分割线 本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/4138745.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

TypeScript 的 npm 包体积逐渐变小

微软高级软件工程师、TypeScript 工具链开发者 Jake Bailey 表示,TypeScript 5.3 的体积将会比 5.2 减小 20%。 他介绍了部分采取的举措: 在 4.9 中删除了一些自 3.7 以来不小心被引入到软件包的文件 在 5.0 中删除 module 在 5.3 中,采用 tsserverlibrary.js 取代 typescript.js …… 下面是 TypeScript 各版本的包体积变化情况: Rob Palmer 大佬表示,TypeScript 未来选择提供 ESM 可执行文件后还会变得更加小。 TypeScript 5.2 上周发布了首个 RC 版本,此版本实现了即将推出的 ECMAScript 功能,称为装饰器元数据。此功能的关键思想是使装饰器可以轻松地在其使用的任何类上创建和使用元数据。 延伸阅读 阮一峰发布《TypeScript 教程》

优秀的个人博客,低调大师

Android 自定义控件之SlidingMenuVertical顶部悬浮(垂直折叠抽屉,有滑动渐变回调,可自行添加渐变动画)

GitHub APK 使用方法 将libray模块复制到项目中,或者直接在build.gradle中依赖: allprojects { repositories { maven { url 'https://jitpack.io' } } } dependencies { compile 'com.github.AnJiaoDe:SlidingMenuVertical:V1.1.2' } 注意:如果sync报错,是因为和com.android.tools.build:gradle 3.0有关,可以改将compile改为implementation 或者api 状态栏全透明请参考 注意:布局一定是SlidingMenuVertical包含2个直接子View <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.cy.translucentparent.StatusBarView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ff3F51B5"/> <RelativeLayout android:layout_width="match_parent" android:layout_height="48dp" android:background="#ff3F51B5"> <ImageView android:layout_width="wrap_content" android:layout_height="match_parent" android:padding="10dp" android:scaleType="centerInside" android:src="@drawable/back" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="抽屉" android:textColor="#ffffff" /> <TextView android:id="@+id/tv_switch" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_alignParentRight="true" android:gravity="center" android:padding="10dp" android:text="开关" android:textColor="#ffffff" /> </RelativeLayout> <com.cy.slidemenuvertical.SlidingMenuVertical android:id="@+id/slidingMenu" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#33454545" android:text="上面面\n上面面\n上面面\n上面面\n上面面\n上面面\n上面面\n上面面\n上面面\n上面面\n上面面\n上面面\n上面面\n上面面\n上面面\n" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/tv_middle" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:paddingBottom="10dp" android:paddingTop="10dp" android:text="悬浮" android:textColor="#454545" /> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:background="#e6e6e6" android:overScrollMode="never" android:scrollbars="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="下面\n下面\n下面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n下面\n菜逼" /> </ScrollView> </LinearLayout> </com.cy.slidemenuvertical.SlidingMenuVertical> </LinearLayout> public abstract class BaseActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); StatusNavUtils.setStatusBarColor(this,0x00000000); } public void startAppcompatActivity(Class<?> cls) { startActivity(new Intent(this, cls)); } } public class MainActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final TextView tv_middle = (TextView) findViewById(R.id.tv_middle); final SlidingMenuVertical slidingMenuVertical = ((SlidingMenuVertical) findViewById(R.id.slidingMenu)); slidingMenuVertical.setDuration_max(300);//设置 设置松手后 开闭最长过渡时间 slidingMenuVertical.setAmbit_scroll(100);//修改滑动界限 值,值越大 开闭越难 单位ms slidingMenuVertical.setOnSwitchListener(new SlidingMenuVertical.OnSwitchListener() { /* 滑动中 y_now:实时view_bottom的top y, y_opened:抽屉打开时view_bootom的top y,y_closed:抽屉关闭时view_bottom的top y top y:在屏幕中的top y坐标 */ @Override public void onSwitching(boolean isToOpen, int y_now, int y_opened, int y_closed) { tv_middle.setBackgroundColor(Color.argb((int) (1.0f * (y_opened - y_now) / (y_opened - y_closed) * 255), Color.red(0xff3F51B5), Color.green(0xff3F51B5), Color.blue(0xff3F51B5))); tv_middle.setTextColor(Color.argb((int) (1.0f * (y_opened - y_now) / (y_opened - y_closed) * 255), Color.red(0xffffffff), Color.green(0xffffffff), Color.blue(0xffffffff))); } @Override public void onSwitched(boolean opened) { if (opened) { tv_middle.setBackgroundColor(0xffffffff); tv_middle.setTextColor(0xff454545); } } }); findViewById(R.id.tv_switch).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { slidingMenuVertical.open(!slidingMenuVertical.isOpened()); } }); } @Override public void onClick(View v) { } } 源码 SlidingMenuVertical public class SlidingMenuVertical extends LinearLayout { private Scroller mScroller; private View view_top; private View view_bottom; private float downX; private float downY; private boolean opened = true;//状态是否开闭 private OnSwitchListener onSwitchListener; private int duration_max = 300;//最长过度时间 private int ambit_scroll = 100;//滑动界限,开闭 private int y_opened = -1; // * y_opened:抽屉打开时view_bootom的top y public SlidingMenuVertical(Context context) { this(context, null); } public SlidingMenuVertical(Context context, AttributeSet attrs) { super(context, attrs); mScroller = new Scroller(context); setOrientation(VERTICAL); } @Override protected void onFinishInflate() { // 当xml解析完成时的回调 view_top = getChildAt(0); view_bottom = getChildAt(1); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); view_top.measure(widthMeasureSpec, ViewMeasureUtils.getChildHeightMeasureSpec(view_top, heightMeasureSpec)); // view_middle.measure(widthMeasureSpec,ViewMeasureUtils.getChildHeightMeasureSpec(view_middle,heightMeasureSpec)); view_bottom.measure(widthMeasureSpec, heightMeasureSpec); } @Override public boolean onInterceptTouchEvent(MotionEvent event) { setY_opened(); // 拦截 // 竖直滑动时,去拦截 switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = event.getX(); downY = event.getY(); break; case MotionEvent.ACTION_MOVE: float moveX = event.getX(); float moveY = event.getY(); // 竖直滑动 if (Math.abs(moveY - downY) > Math.abs(moveX - downX)) { //上面隐藏 if (opened == false) { return false; } //上面显示并且下滑 if (opened == true && (moveY - downY) > 0) { return false; } return true; } break; case MotionEvent.ACTION_UP: break; default: break; } return super.onInterceptTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = event.getX(); downY = event.getY(); break; case MotionEvent.ACTION_MOVE: float moveX = event.getX(); float moveY = event.getY(); int dy = (int) (downY - moveY + 0.5f);// 四舍五入 20.9 + 0.5-->20 // Log.e("dy","++++++++++++++++++++++++++++"+dy); int scrollY = getScrollY(); //mDownY - moveY>0上滑 if (scrollY + dy > 0) { scrollBy(0, dy); if (scrollY + dy > getHeight_top()) { scrollTo(0, getHeight_top()); } } downX = moveX; downY = moveY; break; case MotionEvent.ACTION_UP: // Log.e("heigth_top", "+++++++++++++++++" + height_top); // Log.e("scrollY", "+++++++++++++++++" + getScrollY()); if (opened) { open(!(getScrollY() > ambit_scroll || getScrollY() > getHeight_top() / 3)); } else { open(getScrollY() < getHeight_top() - ambit_scroll || getScrollY() < getHeight_top() * 2 / 3); } break; } // 消费掉 return true; } /** * 开闭抽屉 * * @param open */ public void open(boolean open) { setY_opened(); this.opened = open; //打开 if (open) { // Log.e("打开", "+++++++++++++++++++++++++++++"); int startX = getScrollX();// 起始的坐标X int startY = getScrollY();// 起始的坐标Y int endX = 0; int endY = 0; int dx = endX - startX;// 增量X int dy = endY - startY;// 增量Y // 1px = 10 int duration = Math.abs(dy) * 10; if (duration > duration_max) { duration = duration_max; } mScroller.startScroll(startX, startY, dx, dy, duration); } else { Log.e("关闭", "+++++++++++++++++++++++++++++" + getScrollY()); int startX = getScrollX();// 起始的坐标X int startY = getScrollY();// 起始的坐标Y int endX = 0; int endY = getHeight_top(); int dx = endX - startX;// 增量X int dy = endY - startY;// 增量Y // 1px = 10 int duration = Math.abs(dy) * 10; if (duration > duration_max) { duration = duration_max; } // 模拟数据变化 mScroller.startScroll(startX, startY, dx, dy, duration); } invalidate();// 触发ui绘制 --> draw() --> dispatchDraw()--> drawChild --> } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) {// 如果正在计算的过程中 // 更新滚动的位置 scrollTo(0, mScroller.getCurrY()); invalidate(); } } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); // Log.e("y_now", ScreenUtils.getViewScreenLocation(view_bottom)[1] + "++++++++++++++++++++++"); // // Log.e("y_closed", y_opened - height_top + "++++++++++++++++++++++"); if (onSwitchListener != null) { onSwitchListener.onSwitching(t - oldt < 0 ? true : false, getY_now(), getY_opened(), getY_opened() - getHeight_top()); if (getY_now() == getY_opened()) { // Log.e("true", "++++++++++++++++++++++++"); onSwitchListener.onSwitched(true); } if (getY_now() == getY_opened() - getHeight_top()) { // Log.e("false", "++++++++++++++++++++++++"); onSwitchListener.onSwitched(false); } } } public boolean isOpened() { return opened; } public int getDuration_max() { return duration_max; } /** * 设置松手后 开闭最长过渡时间 * * @param duration_max */ public void setDuration_max(int duration_max) { this.duration_max = duration_max; } public View getView_top() { return view_top; } public View getView_bottom() { return view_bottom; } public int getHeight_top() { return view_top.getMeasuredHeight(); } /** * 获取 * y_opened:抽屉打开时view_bootom的top y */ private void setY_opened(){ if (y_opened<0){ y_opened=getViewScreenLocation(view_bottom)[1]; Log.e("y _open",y_opened+"++++++++++++++++++++"); } } /** * y_opened:抽屉打开时view_bootom的top y * * @return */ public int getY_opened() { if (y_opened<0){ Log.e("还未计算出来","+++++++++++++++++++++++++++++++++++"); return 0; } return y_opened; } /** * y_now:抽屉实时view_bootom的top y * * @return */ public int getY_now() { return getViewScreenLocation(view_bottom)[1]; } public int getAmbit_scroll() { return ambit_scroll; } /** * 修改滑动界限 值,值越大 开闭越难 单位ms * * @param ambit_scroll <height_top */ public void setAmbit_scroll(int ambit_scroll) { this.ambit_scroll = ambit_scroll; } /** * 计算指定的 View 在屏幕中的坐标。 */ public int[] getViewScreenLocation(View view) { int[] location = new int[2]; // 获取控件在屏幕中的位置,返回的数组分别为控件左顶点的 x、y 的值 view.getLocationOnScreen(location); return location; } public interface OnSwitchListener { /* 滑动中 y_now:实时view_bottom的top y, y_opened:抽屉打开时view_bootom的top y,y_closed:抽屉关闭时view_bottom的top y top y:在屏幕中的top y坐标 */ public void onSwitching(boolean isToOpen, int y_now, int y_opened, int y_closed); /* 滑动停止,状态是否开闭 */ public void onSwitched(boolean opened); } public void setOnSwitchListener(OnSwitchListener onSwitchListener) { this.onSwitchListener = onSwitchListener; } } ViewMeasureUtils public class ViewMeasureUtils { /** * 根据父 View 规则和子 View 的 LayoutParams,计算子类的宽度(width)测量规则 * * @param view */ public static int getChildWidthMeasureSpec(View view, int parentWidthMeasureSpec) { // 获取父 View 的测量模式 int parentWidthMode = MeasureSpec.getMode(parentWidthMeasureSpec); // 获取父 View 的测量尺寸 int parentWidthSize = MeasureSpec.getSize(parentWidthMeasureSpec); // 定义子 View 的测量规则 int childWidthMeasureSpec = 0; // 获取子 View 的 LayoutParams ViewGroup.LayoutParams layoutParams = (ViewGroup.LayoutParams) view.getLayoutParams(); if (parentWidthMode == MeasureSpec.EXACTLY || parentWidthMode == MeasureSpec.AT_MOST) { /* 这是当父类的模式是 dp 的情况 */ if (layoutParams.width > 0) { childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(layoutParams.width, MeasureSpec.EXACTLY); } else if (layoutParams.width == ViewGroup.LayoutParams.WRAP_CONTENT) { childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(parentWidthSize, MeasureSpec.AT_MOST); } else if (layoutParams.width == ViewGroup.LayoutParams.MATCH_PARENT) { childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(parentWidthSize, MeasureSpec.EXACTLY); } } else if (parentWidthMode == MeasureSpec.UNSPECIFIED) { /* 这是当父类的模式是 MATCH_PARENT 的情况 */ if (layoutParams.width > 0) { childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(layoutParams.width, MeasureSpec.EXACTLY); } else if (layoutParams.width == ViewGroup.LayoutParams.WRAP_CONTENT) { childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } else if (layoutParams.width == ViewGroup.LayoutParams.MATCH_PARENT) { childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } } // 返回子 View 的测量规则 return childWidthMeasureSpec; } /** * 根据父 View 规则和子 View 的 LayoutParams,计算子类的宽度(width)测量规则 * * @param view */ public static int getChildHeightMeasureSpec(View view, int parentHeightMeasureSpec) { // 获取父 View 的测量模式 int parentHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec); // 获取父 View 的测量尺寸 int parentHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec); // 定义子 View 的测量规则 int childHeightMeasureSpec = 0; // 获取子 View 的 LayoutParams ViewGroup.LayoutParams layoutParams = (ViewGroup.LayoutParams) view.getLayoutParams(); if (parentHeightMode == MeasureSpec.EXACTLY || parentHeightMode == MeasureSpec.AT_MOST) { /* 这是当父类的模式是 dp 的情况 */ if (layoutParams.height > 0) { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY); } else if (layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(parentHeightSize, MeasureSpec.AT_MOST); } else if (layoutParams.width == ViewGroup.LayoutParams.MATCH_PARENT) { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(parentHeightSize, MeasureSpec.EXACTLY); } } else if (parentHeightMode == MeasureSpec.UNSPECIFIED) { /* 这是当父类的模式是 MATCH_PARENT 的情况 */ if (layoutParams.height > 0) { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY); } else if (layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } else if (layoutParams.height == ViewGroup.LayoutParams.MATCH_PARENT) { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } } // 返回子 View 的测量规则 return childHeightMeasureSpec; } } GitHub 关注专题Android开发常用开源库 简书 微信公众号 QQ群

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册