zoukankan      html  css  js  c++  java
  • view 相关代码片段笔记

    代码中动态创建view,并把AttributeSet加入到当前自定义的view中,动态创建属性相关

     //https://blog.csdn.net/chenhuakang/article/details/53584429
        public static AttributeSet getAttribute(Context ctx,int layoutId){
            XmlPullParser parser = null;
            AttributeSet attributes = null;
            int type;
            try{
                parser = ctx.getResources().getXml(layoutId);//R.layout.textview
                attributes = Xml.asAttributeSet(parser);
                while ((type = parser.next()) != XmlPullParser.START_TAG &&
                        type != XmlPullParser.END_DOCUMENT) {
                    // Empty
                }
    
                if (type != XmlPullParser.START_TAG) {
                    throw new InflateException(parser.getPositionDescription()
                            + ": No start tag found!");
                }
            }catch (Resources.NotFoundException e){
                throw new IllegalArgumentException("xml file not found error!");
            }
            catch (XmlPullParserException e) {
                InflateException ex = new InflateException(e.getMessage());
                ex.initCause(e);
                throw ex;
            } catch (IOException e) {
                InflateException ex = new InflateException(
                        parser.getPositionDescription()
                                + ": " + e.getMessage());
                ex.initCause(e);
                throw ex;
            }
            return attributes;
        }
    

    使用:

     AttributeSet attr =  ViewsHelper.getAttribute(act, R.layout.template_setitem);
                SettingItemCommon commonSettingItem = new SettingItemCommon(act,attr);
                commonSettingItem.setItemContent(item.name,item.desc,true);
    

    Recycleview属性分割线处理

    public static void initRecycleViewParams(RecyclerView rl,boolean needDivide){
            LinearLayoutManager layoutMag = new LinearLayoutManager(AppAppliacation.getAppContext());
            layoutMag.setOrientation(LinearLayoutManager.VERTICAL);
            rl.setLayoutManager(layoutMag);
    
            if(needDivide) {
                DividerItemDecoration divider = new DividerItemDecoration(rl.getContext(), DividerItemDecoration.VERTICAL);
                divider.setDrawable(ContextCompat.getDrawable(rl.getContext(), R.drawable.divider2));
                rl.addItemDecoration(divider);
            }
        }
    

    绘图内容在padding外显示(默认为内部)

    clipToPadding就是说控件的绘制区域是否在padding里面的
    clipChildren是指子控件是否超过padding区域
    两个属性设置了false那么这样子控件就能画到padding的区域了。

     获取activity contentview视图

    activity.findViewById(Window.ID_ANDROID_CONTENT)
    

    or

    // Hijack the decorview
    		ViewGroup decorView = (ViewGroup)activity.getWindow().getDecorView();
    		View oldScreen = decorView.getChildAt(0);
    		decorView.removeViewAt(0);
    
    		// Setup the slider panel and attach it to the decor
    		SliderPanel panel = new SliderPanel(activity, oldScreen, config);
    		panel.setId(R.id.slidable_panel);
    		oldScreen.setId(R.id.slidable_content);
    		panel.addView(oldScreen);
    		decorView.addView(panel, 0);
    

      

     viewTree绘制状态监听:

    (1)ViewTreeObserver实现

    final ViewTreeObserver observer = layoutContainer.getViewTreeObserver();
            observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    //判断ViewTreeObserver 是否alive,如果存活的话移除这个观察者
                    if(observer.isAlive()){
                        observer.removeOnGlobalLayoutListener(this);
                        int viewWidth=view.getMeasuredWidth();
                        int viewHeight=view.getMeasuredHeight();
                    }
                }
            });
            observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
                @Override
                public void onDraw() {
                    if(observer.isAlive()){
                        observer.removeOnDrawListener(this);
                    }
                }
            });
    

     (2)Choreographer方式:

    @Override
        protected void onResume() {
            super.onResume();
            Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
                @Override
                public void doFrame(long frameTimeNanos) {
                    start = SystemClock.uptimeMillis();
                    log("绘制开始:height = "+view.getHeight());
                }
            });
        }
    

    在activity中获取fragment中的控件
     getFragmentManager().findFragmentById(id).getView().findViewById(id)

    EditText click事件无反应问题,

    原因:touch事件影响 OnTouch -> OnFocusChange -> OnClick.

    解决:使用TouchListener替换Click事件

    edit.setOnTouchListener(new View.OnTouchListener() {//click事件处理
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if(MotionEvent.ACTION_UP == event.getAction()){
                            if(null!=changeLayout)
                                changeLayout.setVisibility(View.GONE);
                        }
                        return false;//注意返回
                    }
                });
    

     自定义处理focus:

    禁用 android:focusable="false"

    设置focusListener

    //            edit.setOnFocusChangeListener(new View.OnFocusChangeListener() {//焦点处理
    //                @Override
    //                public void onFocusChange(View v, boolean hasFocus) {
    //                    if(hasFocus)
    //                        Toast.makeText(getApplicationContext(), "onFocusChange", Toast.LENGTH_LONG).show();
    //                }
    //            });
    

    实现AutoCompleteTextView,SearchView功能

    使用Listview+EditTextview+Filter Adatpter

    1,Filter Adatpter处理

    package com.bjzjkj.net.deviceapp.simcard_module.adapter;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.Filter;
    import android.widget.FrameLayout;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import com.bjzjkj.net.deviceapp.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by yudajun on 2017/6/16.
     * 弹出框下拉样式
     */
    
    public class CommonPopviewListAdapter extends BaseAdapter {
    
        private Context mContext;
        private List<CommonItemModel> sunItems ,filteredData ;
    
        public CommonPopviewListAdapter(Context mContext,List<CommonItemModel> items) {
            this.mContext = mContext;
            this.sunItems = items;
            this.filteredData = items;
        }
    
        public void setData(List<CommonItemModel> items){
            this.sunItems = items;
            this.filteredData = items;
            notifyDataSetChanged();
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            HolderView holderView;
            // Important to not just null check, but rather to a instanceof
            // since we might get any subclass of view here.
            if (convertView instanceof HolderView) {
                holderView = (HolderView) convertView;
            } else {
                holderView = new HolderView(mContext, null);
            }
            holderView.bindData(filteredData.get(position).text);
            return holderView;
        }
    
        @Override
        public int getCount() {
            return filteredData.size();
        }
    
        @Override
        public CommonItemModel getItem(int position) {
            return filteredData.get(position);
        }
    
        @Override
        public long getItemId(int id) {
            return id;
        }
    
        private ItemFilter mFilter = new ItemFilter();
    
        public Filter getFilter() {
            return mFilter;
        }
    
        private class HolderView extends FrameLayout {
            private ImageView ivIcon;
            private TextView tvTitle;
    
            public HolderView(Context context, AttributeSet attrs) {
                super(context, attrs);
                View v = LayoutInflater.from(context).inflate(R.layout.common_pop_item, this);
                tvTitle = (TextView) v.findViewById(R.id.tvTitle);
            }
    
            public void bindData(String title) {
                tvTitle.setText(title);
            }
        }
    
        private class ItemFilter extends Filter {//过滤匹配结果
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                String filterString = constraint.toString().toLowerCase();
    
                FilterResults results = new FilterResults();
    
                final List<CommonItemModel> list = sunItems;
    
                int count = list.size();
                final List<CommonItemModel> nlist = new ArrayList<CommonItemModel>(count);
    
                String filterableString ;
    
                for (int i = 0; i < count; i++) {
                    filterableString = list.get(i).text;
                    if (filterableString.toLowerCase().contains(filterString)) {
                        nlist.add(list.get(i));
                    }
                }
    
                results.values = nlist;
                results.count = nlist.size();
    
                return results;
            }
    
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                filteredData = (List<CommonItemModel>) results.values;
                notifyDataSetChanged();
            }
        }
    
        public static class CommonItemModel{
            public String text;
            public String workShopId;//车间id
            public String productId;
            public String typeDetail;
        }
    
    }
    

    2, EditText监听

    @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
            }
    
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                mSearchContentLv.setVisibility(View.VISIBLE);
                mSearchableAdapter.getFilter().filter(s.toString());
            }
    
            @Override
            public void afterTextChanged(Editable s) {
    
            }
    
    HolderView item view 处理
    
    @Override
    public View getView(int i, View convertView, ViewGroup viewGroup) {
        HolderView holderView;
        // Important to not just null check, but rather to a instanceof
        // since we might get any subclass of view here.
        if (convertView instanceof HolderView) {
            holderView = (HolderView) convertView;
        } else {
            holderView = new HolderView(mContext);
        }
        holderView.bind(new Digit(i));
    
        return holderView;
    }
    
    class HolderView extends FrameLayout{
            //private Context ctx;
            private View vroot;
    
            public HolderView(Context context) {
                super(context);
                init(context);
            }
    
            public HolderView(Context context, AttributeSet attrs, View vroot) {
                super(context, attrs);
                init(context);
            }
    
            private void init(Context context){
                vroot = LayoutInflater.from(context).inflate(R.layout.flyrecoder_item, this);
                ButterKnife.bind(this, vroot);
            }
    
    		void bindData(FlyRecordData model){
    					this.tv_fly_record_item_title.setText(model.itemTitle);
    					this.tv_fly_record_title_today.setText(model.todayData);
    		}			
     }
    
    
    在展示窗体内容时添加对view统一处理
    
    mLayoutInflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
            mViewGroup = (ViewGroup) activity
                    .findViewById(android.R.id.content);
    
            mToastView = mLayoutInflater.inflate(R.layout.supertoast,
                    mViewGroup, false);
    
            mMessageTextView = (TextView) mToastView
                    .findViewById(R.id.message_textview);
    
    
    指定content view中头部或底部加入其它的view
    
    private void setPoppyViewOnView(View view) {
    		LayoutParams lp = view.getLayoutParams();
    		ViewParent parent = view.getParent();
    		ViewGroup group = (ViewGroup)parent;
    		int index = group.indexOfChild(view);
    		final FrameLayout newContainer = new FrameLayout(mActivity);
    		group.removeView(view);
    		group.addView(newContainer, index, lp);
    		newContainer.addView(view);
    		final FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    		layoutParams.gravity = mPoppyViewPosition == PoppyViewPosition.BOTTOM ? Gravity.BOTTOM : Gravity.TOP;
    		newContainer.addView(mPoppyView, layoutParams);
    		group.invalidate();
    	}
    
    public enum PoppyViewPosition {
    		TOP, BOTTOM
    	};
    private View mPoppyView;
    

    强制measure childview 方法:

     private void measureView(View child) {
            ViewGroup.LayoutParams p = child.getLayoutParams();
            if (p == null) {
                p = new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.FILL_PARENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT);
            }
    
            int childWidthSpec = ViewGroup.getChildMeasureSpec(0,
                    0 + 0, p.width);
            int lpHeight = p.height;
            int childHeightSpec;
            if (lpHeight > 0) {
                childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
            } else {
                childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
            }
            child.measure(childWidthSpec, childHeightSpec);
        }
    

    设置图片叠加层(参差不齐效果)

    Drawable[] array = new Drawable[2];       
    array[0] = getResources().getDrawable(R.drawable.qq_girl);       
    array[1] = getResources().getDrawable(R.drawable.qq_boy);       
    LayerDrawable la = new LayerDrawable(array);       
    // 其中第一个参数为层的索引号,后面的四个参数分别为left、top、right和bottom       
    la.setLayerInset(0, 0, 0, 0, 0);       
    la.setLayerInset(1, 18, 35, 180, 76);       
    image.setImageDrawable(la);  
    
    也可在xml实现
    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
        <item android:drawable="@drawable/compassbackground" />
        <item android:drawable="@drawable/compass_text" />
    </layer-list>
    

     
    扩大控件有效点击区域(以imageview为例,当图片较小时,点击会有不灵敏感觉)这里需要设置scaleType属性

    改进:
    <ImageView
          android:layout_width="100dp"
          android:layout_height="100dp"
           android:src="@drawable/edit"
          android:scaleType="centerInside"/>
    这里设置路ImageView的大小,这个大小区域就是ImageViwe的有效的点击区域,可以根据自己的情况修改大小
    需要注意的是: 要使用 src 不能使用background 否则图像会被拉伸

    使用TouchDelegate扩展区域:

    public static void setTouchDelegate(final View view, final int expandTouchWidth) {
            final View parentView = (View) view.getParent();
            parentView.post(new Runnable() {
                @Override
                public void run() {
                    final Rect rect = new Rect();
                    view.getHitRect(rect); // view构建完成后才能获取,所以放在post中执行
                    
                    rect.top -= expandTouchWidth;
                    rect.bottom += expandTouchWidth;
                    rect.left -= expandTouchWidth;
                    rect.right += expandTouchWidth;
    
                    parentView.setTouchDelegate(new TouchDelegate(rect, view));
                }
            });
        }
    

    在touch屏幕上某点时,判断点击是否在某个widget控件内:

    Rect mTouchRect = new Rect();
     private boolean isTouchedView(View view, float x, float y) {
            view.getHitRect(mTouchRect);
    
            // by taping top or bottom padding, the list performs on click on a border item.
            // we don't add top padding here to keep behavior consistent.
          //  mTouchRect.top += mTranslateY;
    
          //  mTouchRect.bottom += mTranslateY + getPaddingTop();
          //  mTouchRect.left += getPaddingLeft();
          //  mTouchRect.right -= getPaddingRight();
            return mTouchRect.contains((int)x, (int)y);
        }
    

     
    activity设置背景透明 getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));   

    view背景透明设置
    android:background
    以下两种方法设置背景为透明:"@android :color/transparent"和"@null"

    GirdView,ListView设置divide透明    gridView.setSelector(new ColorDrawable(Color.TRANSPARENT));


    隐去标题栏,  隐去状态栏 android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
    设置透明背景,修改AndroidManifest.xml文件,在对应的Activity里面加上下面的属性:
    android:theme="@android:style/Theme.Translucent"
    使用系统背景作为应用的背景,在onCreate的时候添加窗口标志:
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
    android:theme="@android:style/Theme.Dialog"


    dialog级别设置 ctx不依赖Activity
     AlertDialog mDialog=dialog.create();  
     mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);//设定为系统级警告,关键   

    <activity android:windowSoftInputMode="stateVisible|adjustResize" . . . >
     该Activity主窗口总是被调整屏幕的大小以便留出软键盘的空间

    //强制为横屏   
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  
    <activity android:name=".HandlerActivity" android:screenOrientation="landscape"/>  

    //强制为竖屏   
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);  
    <activity android:name=".HandlerActivity" android:screenOrientation="portrait"/>

    AndroidManifest.xml 中设置属性禁止重新创建Activity,并且添加屏幕切换监听。
    <activity android:name=".HandlerActivity"
    sdk<3.2 android:configChanges="orientation|keyboardHidden"/>
    dk>3.2 android:configChanges="orientation|screenSize"



    handler清理所有消息内容   mHandler.removeCallbacksAndMessages(null); 

    //获取View在窗口/屏幕中的位置
    TextView tv= (TextView) findViewById(R.id.tv);
    int loc[]=new int[2];
    tv.getLocationInWindow(loc);
    Log.e("TAG",loc[0]+" "+loc[1]);


    根据widget资源名称获取对应ID:   
    int resID = getResources().getIdentifier("widget_id", "id",  getPackageName());
    View addButton = findViewById(resID);

    View中的isShown()方法,以前都是用view.getVisibility() == View.VISIBLE来判断的,但是与这个函数还是有区别的。
     也就是只有当view本身和它的所有父容器都是visible时,isShown()才返回TRUE。
     而平常我们调用if(view.getVisibility() == View.VISIBLE)只是对view本身而不对父容器的可见性进行判断。


    直接获取view,不需要强制转型

    public static <T> T $(View vroot,int viewID) {
            return (T) vroot.findViewById(viewID);
        }

    使用:
    Button takePicture = Utils.$(v, R.id.start_camera);

    颜色值创建Drawable对象

    private Drawable createDrawable(int color) {
            OvalShape ovalShape = new OvalShape();
            ShapeDrawable shapeDrawable = new ShapeDrawable(ovalShape);
            shapeDrawable.getPaint().setColor(color);
     
            if (mShadow && !hasLollipopApi()) {
                Drawable shadowDrawable = getResources().getDrawable(mType == TYPE_NORMAL ? R.drawable.fab_shadow
                        : R.drawable.fab_shadow_mini);
                LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{shadowDrawable, shapeDrawable});
                layerDrawable.setLayerInset(1, mShadowSize, mShadowSize, mShadowSize, mShadowSize);
                return layerDrawable;
            } else {
                return shapeDrawable;
            }
        }
    

     代码实现按钮按压效果颜色变化:

    private void updateBackground() {
            StateListDrawable drawable = new StateListDrawable();
            drawable.addState(new int[]{android.R.attr.state_pressed}, createDrawable(mColorPressed));
            drawable.addState(new int[]{-android.R.attr.state_enabled}, createDrawable(mColorDisabled));
            drawable.addState(new int[]{}, createDrawable(mColorNormal));
            setBackground(drawable);
        }
    

     悬浮属性设置:

    UC浏览器中文版出了一个快速搜索的功能,
    显示这个悬浮窗不需要申请android.permission.SYSTEM_ALERT_WINDOW权限
    一般设置成TYPE_PHONE就可以悬浮在很多view的上方了, 但是调用这个方法需要申请android.permission.SYSTEM_ALERT_WINDOW权限,
    将type设置成TYPE_TOAST果然有奇效, 但是在2.3上不能接收点击事件.
    TYPE_APPLICATION_PANEL: 只能配合Activity在当前APP使用(PopupWindow默认就是这个Type)
    TYPE_CHANGED: 只能配合Activity在当前APP使用


    绘制扇形进度加载
    
    public void draw(Canvas canvas) {
            if (getHideWhenZero() && mLevel == 0) {
                return;
            }
            drawBar(canvas, maxLevel, getBackgroundColor());
            drawBar(canvas, mLevel, getColor());
        }
        
        private void drawBar(Canvas canvas, int level, int color) {
            Rect bounds = getBounds();
            RectF rectF = new RectF((float) (bounds.right * .4), (float) (bounds.bottom * .4),
                    (float) (bounds.right * .6), (float) (bounds.bottom * .6));
            mPaint.setColor(color);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(6);
            if (level != 0)
                canvas.drawArc(rectF, 0, (float) (level * 360 / maxLevel), false, mPaint);
        }
    
    
    屏幕截取
    
    /**
         * 获取当前屏幕截图,包含状态栏
         */
        public static Bitmap snapShotWithStatusBar(Activity activity){
            View view = activity.getWindow().getDecorView();
            view.setDrawingCacheEnabled(true);
            view.buildDrawingCache();
            Bitmap bmp = view.getDrawingCache();
            int width = getScreenWidth(activity);
            int height = getScreenHeight(activity);
            Bitmap bp = null;
            bp = Bitmap.createBitmap(bmp, 0, 0, width, height);
            view.destroyDrawingCache();
            return bp;
        }
     
        /**
         * 获取当前屏幕截图,不包含状态栏
         *
         */
        public static Bitmap snapShotWithoutStatusBar(Activity activity){
            View view = activity.getWindow().getDecorView();
            view.setDrawingCacheEnabled(true);
            view.buildDrawingCache();
            Bitmap bmp = view.getDrawingCache();
            Rect frame = new Rect();
            activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
            int statusBarHeight = frame.top;
            int width = getScreenWidth(activity);
            int height = getScreenHeight(activity);
            Bitmap bp = null;
            bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height
                    - statusBarHeight);
            view.destroyDrawingCache();
            return bp;
        }
    
    Bitmap大小计算
    
    static int getBitmapBytes(Bitmap bitmap) {
        int result;
        if (SDK_INT >= HONEYCOMB_MR1) {
          result = BitmapHoneycombMR1.getByteCount(bitmap);
        } else {
          result = bitmap.getRowBytes() * bitmap.getHeight();
        }
        if (result < 0) {
          throw new IllegalStateException("Negative size: " + bitmap);
        }
        return result;
      }
    
    
    保存恢复ListView当前位置
    
    private void saveCurrentPosition() {
            if (mListView != null) {
                int position = mListView.getFirstVisiblePosition();
                View v = mListView.getChildAt(0);
                int top = (v == null) ? 0 : v.getTop();
                //保存position和top
            }
        }
        
        private void restorePosition() {
            if (mFolder != null && mListView != null) {
                int position = 0;//取出保存的数据
                int top = 0;//取出保存的数据
                mListView.setSelectionFromTop(position, top);
            }
        }
    
    
    帮助、about、关于作者、HELP等的提示dialog页面
    
    	//方法一:
     AlertDialog ad = new AlertDialog.Builder(SettingPreference.this)
    	                        .setTitle(R.string.about_dlg_title)
    	                        .setMessage(R.string.about_dlg_message)
    	                        .setPositiveButton(getText(R.string.ok), null).create();
    	                ad.show();
    					//加入链接功能
    	                Linkify.addLinks((TextView) ad.findViewById(android.R.id.message),
    	                        Linkify.ALL);
    
    //方法二:
    //设计一个AboutDialog类继承于AlertDialog
    public class AboutDialog extends AlertDialog {   
        public AboutDialog(Context context) {   
            super(context);   
            final View view = getLayoutInflater().inflate(R.layout.about,   
                    null);   
            setButton(context.getText(R.string.close), (OnClickListener) null);   
            setIcon(R.drawable.icon_about);   
            setTitle("程序版本   v1.0.0" );   
            setView(view);   
        }   
    

    布局文件about.xml

    <?xml version="1.0" encoding="utf-8"?>  
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
        android:layout_width="fill_parent" android:layout_height="wrap_content">  
        <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
            android:layout_width="fill_parent" android:layout_height="fill_parent">  
       
            <TextView android:layout_height="fill_parent" 
                android:layout_width="fill_parent" android:text="@string/help_dialog_text" 
                android:padding="6dip" android:textColor="#FFFFFF" />  
        </ScrollView>  
    </FrameLayout>  
    



    自定义View相关问题:

    measure解析:

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    		int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
    		int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
    		setMeasuredDimension(width, height);
    	}
    
    
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    		int count = getChildCount();
    
    		int maxHeight = 0;
    		int maxWidth = 0;
    
    		measureChildren(widthMeasureSpec, heightMeasureSpec);
    
    		for (int i = 0; i < count; i++) {
    			View child = getChildAt(i);
    			if (child.getVisibility() != GONE) {
    				int childRight;
    				int childBottom;
    
    				CenterLayout.LayoutParams lp = (CenterLayout.LayoutParams) child.getLayoutParams();
    
    				childRight = lp.x + child.getMeasuredWidth();
    				childBottom = lp.y + child.getMeasuredHeight();
    
    				maxWidth = Math.max(maxWidth, childRight);
    				maxHeight = Math.max(maxHeight, childBottom);
    			}
    		}
    
    		maxWidth += mPaddingLeft + mPaddingRight;
    		maxHeight += mPaddingTop + mPaddingBottom;
    
    		maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
    		maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
    
    		setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec));
    	}
    
    @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            //DensityUtils.dp2px(getContext(),40)+
            int minWidth = getPaddingLeft() + getPaddingRight();
            int minHeight = barHeight + getPaddingBottom() + getPaddingTop();
    
            int w = resolveSizeAndState(minWidth, widthMeasureSpec, 0);
            int h = resolveSizeAndState(minHeight, heightMeasureSpec, 0);
    
            setMeasuredDimension(w, h);
        }
    

    绘制文本居中显示:

     public void drawTextCentredInRectWithSides(Canvas canvas, Paint paint, String text, float left, float top, float right, float bottom) {
            paint.setTextAlign(Paint.Align.CENTER);
    
            float textHeight = paint.descent() - paint.ascent();
            float textOffset = (textHeight / 2) - paint.descent();
    
            canvas.drawText(text, (left + right) / 2, (top + bottom) / 2 + textOffset, paint);
        }
    

    绘制局部圆角

    1,绘制完整圆角 canvas.drawRoundRect

    2,去除部分圆角,在要去除地方,在绘制一次小的矩形使其变为方角

        private void clipTopLeft(final Canvas canvas, final Paint paint, int offset,int left,int top) {
            Rect block = new Rect(left, top, left+offset, top+offset);
            canvas.drawRect(block, paint);
        }
    
        private void clipTopRight(final Canvas canvas, final Paint paint, int offset, int right,int top) {
            Rect block = new Rect(right - offset, top, right, top+offset);
            canvas.drawRect(block, paint);
        }
    
        private void clipBottomLeft(final Canvas canvas, final Paint paint, int offset, int left, int bottom) {
            Rect block = new Rect(left, bottom - offset, left+offset, bottom);
            canvas.drawRect(block, paint);
        }
    
        private void clipBottomRight(final Canvas canvas, final Paint paint, int offset, int right, int bottom) {
            Rect block = new Rect(right - offset, bottom - offset, right, bottom);
            canvas.drawRect(block, paint);
        }
    

     带进度webview

    public class ProgressWebView extends WebView {
     
        private ProgressBar progressbar;
     
        public ProgressWebView(Context context, AttributeSet attrs) {
            super(context, attrs);
            progressbar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);
            progressbar.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 3, 0, 0));
            addView(progressbar);
            //        setWebViewClient(new WebViewClient(){});
            setWebChromeClient(new WebChromeClient());
        }
     
        public class WebChromeClient extends android.webkit.WebChromeClient {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                if (newProgress == 100) {
                    progressbar.setVisibility(GONE);
                } else {
                    if (progressbar.getVisibility() == GONE)
                        progressbar.setVisibility(VISIBLE);
                    progressbar.setProgress(newProgress);
                }
                super.onProgressChanged(view, newProgress);
            }
     
        }
     
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            LayoutParams lp = (LayoutParams) progressbar.getLayoutParams();
            lp.x = l;
            lp.y = t;
            progressbar.setLayoutParams(lp);
            super.onScrollChanged(l, t, oldl, oldt);
        }
    }
    

     textview文字图片一起水平居中

    public class DrawableCenterTextView extends TextView {
    ......
        @Override
        protected void onDraw(Canvas canvas) {
            Drawable[] drawables = getCompoundDrawables();
            if (drawables != null) {
                Drawable drawableLeft = drawables[0];
                if (drawableLeft != null) {//左边图片处理
                    float textWidth = getPaint().measureText(getText().toString());
                    int drawablePadding = getCompoundDrawablePadding();
                    int drawableWidth = 0;
                    drawableWidth = drawableLeft.getIntrinsicWidth();
                    float bodyWidth = textWidth + drawableWidth + drawablePadding;
                    canvas.translate((getWidth() - bodyWidth) / 2, 0);
                }
            }
             
            Drawable drawableRight = drawables[2];
            if (drawableRight != null) {//右边图像处理
                float textWidth = getPaint().measureText(getText().toString());
                int drawablePadding = getCompoundDrawablePadding();
                int drawableWidth = 0;
                drawableWidth = drawableLeft.getIntrinsicWidth();
                float bodyWidth = textWidth + drawableWidth + drawablePadding;
                setPadding(0, 0, (int)(getWidth() - bodyWidth), 0);
                canvas.translate((getWidth() - bodyWidth) / 2, 0);
            }
            super.onDraw(canvas);
        }
         
    }
    

    底部导航tab中间button高出一部分内容

    <?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:clipChildren="false"
        android:orientation="vertical" >
     
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="48dip"
            android:background="#B0C4DE"
            android:orientation="horizontal" >
     
            <ImageView
                android:layout_width="0dip"
                android:layout_height="fill_parent"
                android:layout_weight="1.0"
                android:scaleType="fitCenter"
                android:src="@drawable/ic_launcher" />
                 
             <ImageView
                 android:layout_width="0dip"
                android:layout_height="64dip"
                android:layout_gravity="bottom"
                android:layout_weight="1.0"
                android:scaleType="fitCenter"
                android:src="@drawable/ic_launcher" />
        </LinearLayout>  
         
    </LinearLayout>   
    

     1、只需在根节点设置android:clipChildren为false即可,默认为true
     2、可以通过android:layout_gravity控制超出的部分如何显示。
     3、android:clipChildren的意思:是否限制子View在其范围内



  • 相关阅读:
    TweenMax参数补充
    jQuery.lazyload详解
    js函数和jquery函数详解
    数数苹果手机中的不科学
    网页全栈工程师要点分析
    瞄了一眼墙外的世界,只能给差评
    脑洞大开的自然语言验证码
    别再迷信 zepto 了
    产品列表页分类筛选、排序的算法实现(PHP)
    大学回顾和C与PHP之路
  • 原文地址:https://www.cnblogs.com/happyxiaoyu02/p/6818930.html
Copyright © 2011-2022 走看看