Toast虽然有setDuration(int duration)来设置显示时间,但是duration只有两个选择,LENGTH_SHORT = 0和LENGTH_LONG = 1,其它值传入后,在底层似乎被忽略了,被当作0和非0来处理,故不能调整显示时间。
如果通过多次show来达到时间累加的效果,由于显示和不显示有渐变的动画效果,则会出现闪烁效果。如果自定义一个类似Toast的View『个人认为,之所以使用Toast,是因为它既能满足和用户进行简单交互,又具有操作简单方便的优势,如果要自定义,为什么一定要是“Toast”的外观呢?=^_^=』,然后添加到窗口,也是一种可行的方法,在此不做说明。看到一个利用反射来实现的文章,在此转一下!:)
此时反射机制就派上了用场,利用反射来控制显示和取消显示。关于部分代码的追踪,可以看这里:http://blog.youkuaiyun.com/droid_zhlu/article/details/7685084
主要代码:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.content.Context;
import android.view.View;
import android.widget.Toast;
public class ReflectToast {
private Toast mToast;
private Field field;
private Object obj;
private Method showMethod, hideMethod;
public ReflectToast(Context context, View v) {
mToast = new Toast(context);
mToast.setView(v);
reflectionTN();
}
public void show() {
try {
showMethod.invoke(obj, null);
} catch (Exception e) {
e.printStackTrace();
}
}
public void cancel() {
try {
hideMethod.invoke(obj, null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void reflectionTN() {
try {
field = mToast.getClass().getDeclaredField("mTN");
field.setAccessible(true);
obj = field.get(mToast);
showMethod = obj.getClass().getDeclaredMethod("show", null);
hideMethod = obj.getClass().getDeclaredMethod("hide", null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
测试 调用代码:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class TestToastDurationActivity extends Activity implements OnClickListener {
private Button showButton;
private Button hideButton;
private ReflectToast toast;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = new TextView(this);
textView.setText("这是一个TextView!");
textView.setBackgroundResource(android.R.drawable.toast_frame);
toast = new ReflectToast(this, textView);
showButton = (Button) findViewById(R.id.button1);
hideButton = (Button) findViewById(R.id.button2);
showButton.setOnClickListener(this);
hideButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (toast == null) {
return;
}
switch (v.getId()) {
case R.id.button1:
toast.show();
break;
case R.id.button2:
toast.cancel();
break;
default:
break;
}
}
@Override
protected void onPause() {
super.onPause();
if (toast != null) {
toast.cancel();
}
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:padding="5dip" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="显示Toast" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="取消Toast" /> </LinearLayout> </LinearLayout>
运行效果:
多说一句:问题是死的,但是解决问题的方法确是灵活多变的!利用反射可以控制Toast的显示和取消,同样可以自定义显示时间,然后在时间耗尽时自动取消,如果你原意的话!