Android 代码技巧

大家知道 AlertDialog 的 context 通常需要是 Activity,所以想在 Service 或者 Receiver 里等无关 Activity 的场景弹对话框怎么办?

代码如下:




public class DialogContainerActivity extends Activity {

    private static DialogContextProvider mContextProvider;

    public static void show(DialogContextProvider contextProvider) {
        mContextProvider = contextProvider;
        Intent intent = new Intent(App.getInstance() /*全局 Application 实例*/, DialogContainerActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        App.getApp().startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContextProvider.getContext(this);
    }

    public interface DialogContextProvider {
        void getContext(Activity activity);
    }
}

然后给它设置个透明的主题,再加点阴影效果。。。全局 Dialog 需要的时候用它的静态方法回调就可以在任意地方拿到 Activity 用来弹 Dialog 了。。。

弹出 Dialog 的话可以这样用:

DialogContainerActivity.show(activity -> {
    AlertDialog.Builder builder = new AlertDialog.Builder(activity);
    builder.setMessage(message);
    builder.setPositiveButton(/*...*/);
    builder.setNegativeButton(/*...*/);
    // 监听 setOnDismissListener 关闭 Container Activity
    closeShadowContainer(builder, activity); 
    builder.show();
});

有人指出,可以直接使用如下方法直接实现:

在 show 之前可以给 dialog 设置属性

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

然后添加权限

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />


经测试 MIUI 下第二种方法是无效的(默认关闭了权限,需要手动开启),我还是用原来的方法吧, 在流氓的环境下还是得用流氓的方法才有用。。。不瞎折腾了


===============================================================


==================================================================


下面是今天刚写的, 没想到居然能够编译通过, 不过还是比较懒
服务器给我的sex有可能为空, 是个字符串, 偷懒直接binding, 然后就写出这么奇怪的代码


<TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:drawablePadding="@dimen/x750_20"
         android:drawableRight="@{TextUtils.isEmpty(post.user.sex)@drawable/icon_boy:Integer.valueOf(post.user.sex)==1? @drawable/icon_boy:@drawable/icon_girl}"
         android:textColor="#595959"
         android:textSize="@dimen/x750_30"
         tools:drawableRight="@drawable/icon_boy"/>





findViewById时的技巧:

public <T extends View> T $(int id) {
    return (T) super.findViewById(id);
}

public <T extends View> T $(View view, int id) {
    return (T) view.findViewById(id);
}


省去了强制转换的代码,非常实用,你第一次看到时,觉得会有瞠目结舌之感,泛型能这么用。熟悉泛型绝对是菜鸟到进阶的必经之路。




定义的接口方法有好几个,但实现的时候可能只处理其中的一个回调。比如android中的默认动画监听:

animation.setAnimationListener(new Animation.AnimationListener() {
@Override
    public void onAnimationStart(Animation animation) {

    }

@Override
    public void onAnimationEnd(Animation animation) {
        //TODO 我可能只要在end的时候隐藏某个控件,其他2个回调方法都不处理
    }

@Override
    public void onAnimationRepeat(Animation animation) {

    }
});

要是嫌篇幅过长,可以定义个类AnimListener实现AnimationListener,调用时只要实现需要处理的回调方法即可:

animation.setAnimationListener(new AnimListener() {
            @Override
            public void onAnimationEnd(Animation animation) {
                super.onAnimationEnd(animation);
            }
        });



字符串格式化,虽然大家可能都会用,但第一次看到,确实是有瞠目结舌之感。

String str = String.format("来自%s的问候~","zhihu");
%s、%d等看着眼熟吧?初学编程时,c语言的打印,有木有印象~~
在strings.xml中这样声明,多个地方引用时,多么的明智。谁用谁知道!!!



在针对多个条件多个操作时,为了避免长篇累牍的switch/if-else,与或运算粉墨登场(ps:c代码写多的码友可以直接跳过)。如:

/**
 * 控制3个按钮的显示隐藏,避免长篇大幅.如果有2个以上显示,对应的值相或,如:1|2|4
 * tv1:0x1
 * tv2:0x2
 * tv3:0x4
 */
void magicAndOrOperation(int mask) {
tv_1.setVisibility((mask & 0x1) == 0x1 ? View.VISIBLE : View.GONE);
    tv_2.setVisibility((mask & 0x2) == 0x2 ? View.VISIBLE : View.GONE);
    tv_3.setVisibility((mask & 0x4) == 0x4 ? View.VISIBLE : View.GONE);
}

实际调用:

case OrderState.STATE_RETURN:
    magicAndOrOperation(2|4);
    //下面是对应之前的写法,上面还有N多状态,对应不同的按钮显示隐藏
    //tv_1.setVisibility(View.GONE);
    //tv_2.setVisibility(View.VISIBLE);
    //tv_3.setVisibility(View.VISIBLE);
    break;

上面孰优孰劣,一看便知。




解决ScrollView和ListView嵌套时ListView高度显示不正确的问题,只需要像下边这样重写onMeasure方法就可以了,同样适用于GridView


public class XListView extends ListView {
   
   public XListView(Context context) {
      super(context);   }
   
   public XListView(Context context, AttributeSet attrs) {
      super(context, attrs);   }

   public XListView(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);   }
   
   @Override   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      int heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);      super.onMeasure(widthMeasureSpec, heightSpec);   }

}







猜你喜欢

转载自blog.csdn.net/u011694328/article/details/53312531