大家知道 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" />
===============================================================
==================================================================
下面是今天刚写的, 没想到居然能够编译通过, 不过还是比较懒
服务器给我的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");
在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); }
}