Android开发技巧总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chaoyangsun/article/details/80177454

1、获取全局Context

编写Application

public class MyApplication extends Application {  
    private static Context context;  
      
    @Override  
    public void onCreate() {  
        //获取Context  
        context = getApplicationContext();  
    }  
      
    //返回  
    public static Context getContextObject(){  
        return context;  
    }  
}

调用

MyApplication.getContextObject(); 

注:application需要注册

<application  
    android:name="包名.MyApplication"  
     ....  
   > 

2、使用autoLink属性 跳转网页,拨打电话,发送邮件等

只需android:autoLink=“web” 点击就能自动跳转网页,简单粗暴

 <TextView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:autoLink="web"
      android:text="www.jeean.cn "/>

只需android:autoLink=“phone” 点击就能自动拨打电话,一样的简单粗暴

 <TextView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:autoLink="phone"
      android:text="18888888888"/>

3、代码中动态设置文字大小时,单位的问题

借助TypedValue设置单位

 textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);//14sp
 textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);//15dp

4、禁止EditText换行

singleLine已经过时,需要使用下面两个属性才能起到作用:

  android:lines="1"
  android:inputType="text"

5、recyclerview使用notifyDataSetChanged时,item里面EditText显示错乱或清空

解决方案有两种,这里只说一种最简单的,应为一般item里面使用EditText时,列表长度都是很有限的,所以直接禁止recyclerview的item的复用就行:

@Override
public void bindViewHolder(final FlexibleAdapter adapter, EntityViewHolder holder, final int position, List payloads) {
    holder.setIsRecyclable(false);
    ...
    holder.editText.setText(value);
    holder.et_content.addTextChangedListener(new TextWatcher() {
         @Override
         public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
         }
         @Override
         public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
         }
         @Override
         public void afterTextChanged(Editable editable) {
             value = editable.toString();
         }
     });
 }

6、recyclerview隐藏某个item后,该item仍然占位的问题

如果只是简单的设置隐藏,那么item虽然不可见了,但是其宽高依然占位,解决办法:

 @Override
 public void bindViewHolder(final FlexibleAdapter adapter, EntityViewHolder holder, final int position, List payloads) {
	 RecyclerView.LayoutParams param = (RecyclerView.LayoutParams) itemView.getLayoutParams();
     itemView.setVisibility(View.GONE);
     param.height = 0;
     param.width = 0;
     itemView.setLayoutParams(param);
 }

7、TextView加载html并异步加载html中的网络图片

加载html一般使用webview,有一些情况,比如html比较简单或xml布局文件不适合嵌入webview,此时可以用TextView组件加载!

  //适合加载纯文本
  textView.setText(Html.fromHtml(html));
  //可以加载带图片的html 如果是网络图片,还需要异步加载
  textView.setText(Html.fromHtml(string, imgGetter, null));

第一种加载纯文本的情况不多说,下面重点说一说异步加载图片的情况:

  public void parseHtml(final String html) {
        final Html.ImageGetter imgGetter = new Html.ImageGetter() //格式语句不一定相同,只要进行网络加载图片即可
        {
            public Drawable getDrawable(String source)
            {
                Drawable drawable = null;
                try
                {
                    drawable = Drawable.createFromStream(new URL(source).openStream(), "");//加载网络图片资源核心语句
                    drawable.setBounds(0, 0,  drawable.getMinimumWidth(), drawable.getIntrinsicHeight());
                }
                catch (Exception e)
                {
                    return new Drawable()
                    {
                        public void setColorFilter(ColorFilter cf) {}
                        public void setAlpha(int alpha) {}
                        public int getOpacity() {
                            return PixelFormat.UNKNOWN;
                        }
                        public void draw(Canvas canvas) {}
                    };
                }
                return drawable;
            }
        };

        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                final Spanned text = Html.fromHtml(html,imgGetter,null);
                handler.post(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        introServer.setText(text);
                    }
                });
            }
        }).start();
    }
}

8、沉浸式模式的实现

只有在Android 4.4及以上系统才支持沉浸式模式,需要重写Activity的onWindowFocusChanged()方法

 @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus && Build.VERSION.SDK_INT >= 19) {
            View decorView = getWindow().getDecorView();
            decorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        }
    }

9、通过BaseActivity获取到当前启动的Activity名称

在onCreate里面实现下面的代码就行:

  Logger.i("CurrentActivity","当前启动的Activity名称为: "+getClass().getSimpleName());
当前启动的Activity名称为: UXCarDetailActivity
当前启动的Activity名称为: GiveUpSeeCarActivity

10、App启动时黑屏或白屏的问题

不做任何处理,点开app时,会出现一瞬间的白屏或黑屏,解决办法是为启动页单独设置一个主题,如下:
@style/AppTheme.Launcher

	<activity
	      android:name=".MainActivity"
	      android:screenOrientation="portrait"
	      android:theme="@style/AppTheme.Launcher">
	      <intent-filter>
	          <action android:name="android.intent.action.MAIN" />
	          <category android:name="android.intent.category.LAUNCHER" />
	      </intent-filter>
	 </activity>

为该主题设置属性android:windowBackground

   <style name="AppTheme.Launcher" parent="AppTheme">
        <item name="android:windowBackground">@drawable/xml_splash_logo</item>
    </style>

xml_splash_logo.xml如下

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:opacity="opaque">

    <item android:drawable="@android:color/white" />
	<!--启动页展示之前 会先显示下面的图片 可以根据需求调整数量和样式-->
    <item >
        <bitmap
            android:gravity="center"
            android:src="@drawable/ud_splash_uxin_logo_normal" />
    </item>

</layer-list>

11、GridView绘制行间分割线

需要自定义,重写dispatchDraw方法即可:

public class CustomGridView extends GridView {

	/**
	 * 绘制GirdView行间分割线: flag为true绘制,否则不绘制
	 */
	private boolean flag;
	
	public void setFlag(boolean flag) {
		this.flag = flag;
	}
	
	public CustomGridView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public CustomGridView(Context context) {
		super(context);
	}

	public CustomGridView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}
	@Override
	protected void dispatchDraw(Canvas canvas) {
		super.dispatchDraw(canvas);
		if (flag){
			customDraw(canvas);
		}
	}

	/**
	 * 绘制GirdView行间分割线: flag为true绘制,否则不绘制
	 * @param canvas
	 */
	private void customDraw(Canvas canvas) {
		Paint localPaint = new Paint();
		localPaint.setStyle(Paint.Style.STROKE);
		localPaint.setColor(getContext().getResources().getColor(R.color.base_D9D9D9));
        int column = getNumColumns();
        int childCount = getChildCount();
		if (column < 1 || childCount <= column) {//只有一行或者没有列数不绘制
		    return;
        }
        int row = childCount % column == 0 ? childCount / column : childCount / column + 1;//行数
        for (int i = 0; i < row - 1; i++) {
            View view = getChildAt(i*column);//拿到第i行第一个子view来计算坐标位置
            //getLeft() + DensityUtil.dip2px(view.getContext(), 20) 加号后面是为了绘制分割线左边距 不需要的可以去掉
            //getRight() - DensityUtil.dip2px(view.getContext(), 20) 减号后面是右边距 不需要可以去掉
            //view.getBottom() + CustomGridView.this.getVerticalSpacing()/2 绘制在每行底部 并考虑verticalSpace属性
            canvas.drawLine(getLeft() + DensityUtil.dip2px(view.getContext(), 20), view.getBottom() + CustomGridView.this.getVerticalSpacing()/2, getRight() - DensityUtil.dip2px(view.getContext(), 20), view.getBottom() + CustomGridView.this.getVerticalSpacing()/2, localPaint);
        }
	}
}	

12、实现ImageView宽度填满屏幕,高度自适应

这个还是比较简单的,主要是使用两个属性:
android:scaleType="fitXY"它的意思是图片按照指定的大小在ImageView中显示,拉伸显示图片,不保持原比例
android:adjustViewBounds="true"它的意思是保持宽高比

    <ImageView
        android:id="@+id/id_iv_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
        android:adjustViewBounds="true"
        />

13、ConstraintLayout属性之Group

问题:当有多个group或者一个group多次设置setReferencedIds时,Group控制的控件可能失效
原因:当group调用group.setVisibility(View.GONE), 触发重绘机制,内部会调用updatePreLayout(ConstraintLayout container)方法,而其他状态setVisibility(View.VISIBLE)、setVisibility(View.INVISIBLE)不会触发该方法!
解决方案:当调用group.setVisibility(View.VISIBLE)、group.setVisibility(View.INVISIBLE)方法时,再调用一下group1.updatePreLayout(container)方法(container时对应group所在的ConstraintLayout控件)即可!
示例

    private void controlGroup() {
        group.setReferencedIds(ids1);//ids1是group控制的组件id 是个数组
        group.setVisibility(View.GONE);
                new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
               //5s之后先将原来隐藏的组件显示 改变控制的组件 再将其隐藏
                group1.setVisibility(View.VISIBLE);
                group1.updatePreLayout(cl3);
                group1.setReferencedIds(ids2);
                group1.setVisibility(View.GONE);
            }
        }, 5000);
    }

14、Android 在使用WebView时页面显示不出来或显示空白

在我的项目里发现https链接的就会出现这个问题,http的没问题。解决办法如下:

webSetting.setDomStorageEnabled(true);//设置DOM Storage缓存

15、关于singleInstance模式的activity启动standard模式的activity的问题

  • 如果当前进程中存在standard模式的activity,即:standardA -> singleInstanceB -> standardA , 这种是正常的,回退顺序是 A -> A -> B.
  • 如果当前进程中不存在standard模式的activity,如:singleInstanceA -> standardB -> singleInstanceC -> standardB , 这时候会有“异常”,理论上这时候回退的顺序是 BBCA, 而实际上B界面并没有再次创建,回退顺序是BCA.
    无意中发现,特此记录。

16、解决ScrollView嵌套RecyclerView/ListView时顶部布局被顶出,RecyclerView抢占焦点的问题

解决办法也很简单,直接在ScrollView的第一层子布局中加入以下代码

android:descendantFocusability="blocksDescendants"

descendantFocusability这个属性共有三个值可供选择:
blocksDescendants :覆盖所有子控件获取焦点(优先级最高)
beforeDescendants :优先于子控件获取焦点
afterDescendants :当子控件不需要焦点时,获取焦点

展开阅读全文

没有更多推荐了,返回首页