Toast虽然有setDuration(int duration)来设置显示时间,但是duration只有两个选择,LENGTH_SHORT = 0和LENGTH_LONG = 1,其它值传入后,在底层似乎被忽略了,被当作0和非0来处理,故不能调整显示时间。
如果通过多次show来达到时间累加的效果,由于显示和不显示有渐变的动画效果,则会出现闪烁效果。如果自定义一个类似Toast的View『个人认为,之所以使用Toast,是因为它既能满足和用户进行简单交互,又具有操作简单方便的优势,如果要自定义,为什么一定要是“Toast”的外观呢?=^_^=』,然后添加到窗口,也是一种可行的方法,在此不做说明。看到一个利用反射来实现的文章,在此转一下!:)
此时反射机制就派上了用场,利用反射来控制显示和取消显示。关于部分代码的追踪,可以看这里:http://blog.csdn.net/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的显示和取消,同样可以自定义显示时间,然后在时间耗尽时自动取消,如果你原意的话!