代码中动态创建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在其范围内

最新文章

  1. 删除sqlserver代理任务脚本
  2. 多线程同步_Monitor
  3. DataStage
  4. 深度优先搜索 codevs 1065 01字符串
  5. Spring读取配置文件
  6. asp.net中runat=&quot;server&quot;的含义
  7. 20160322 javaweb 学习笔记--response验证码实现
  8. 01 - 概述 VTK 6.0 迁移
  9. 前端自动化构建工具Gulp简单入门
  10. php的filesystem基本函数的学习(1)
  11. django 的时区设置
  12. go 统计目录大小
  13. ipad忘记了锁屏密码,已经越狱了
  14. 小tips:JS数值之间的转换,JS中最大的Number是多少?,JS == 与 === 的区别
  15. 《Inside C#》笔记(九) 表达式和运算符
  16. &lt;转&gt;jmeter(二)录制脚本
  17. 第一个appium的Demo
  18. LeetCode--121--卖卖股票的最佳时机
  19. LitJson JavaScriptSerializer
  20. vue、react、angular三大框架对比 &amp;&amp; 与jQuery的对比

热门文章

  1. android 实现检测版本,下载apk更新(附源码)
  2. 增加select的option之间的间距
  3. Ubuntu系统安装搜狗拼音输入法
  4. js 防抖
  5. VSCode 设置启用终端执行yarn
  6. shell_Day09
  7. flutter CustomScrollView多个滑动组件嵌套
  8. spark structured streaming (结构化流) join 操作( 官方文档翻译)
  9. Visio中的图无失真导入LaTeX中
  10. dart的基本使用