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