Android Toast显示时间

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的显示和取消,同样可以自定义显示时间,然后在时间耗尽时自动取消,如果你原意的话!

猜你喜欢

转载自wangleyiang.iteye.com/blog/1773762