比如一个16:9的图片,你缩放成4:3的图片,这个时候FF浏览器是兼容的,但是IE浏览器就挂掉了。
不过toast333回答的的确是正确的,当然他只是做了个说明,同样,高也可以改成宽,但是一般不是特别建议用图片缩放,而且图片缩放对SEO有很大影响,比如主页上一个50*50的图片,这个尺寸的容量大概是1KB左右,但是如果把一个500*500的图片缩放成50*50的,那么用户打开主页的时候,看到的虽然是50*50的图片,但是下载的和访问速度是500*500的图片,所以你主页如果缩放多的话,几MB的容量肯定是有的,对优化影响太大了吧。
在android中toast是一个很好用的控件,可以很方便的通知用户现在手机在做什么或是你已经做了什么或是在做什么就会怎么样......。最近无事总结一下其使用方法。 我们一般的使用方法如下:
[java] view plain copy print?
Toast.makeText(this, "测试", Toast.LENGTH_SHORT).show()
这也是最简单的使用方法,其实Toast还有一些比较高级的使用方法
1、设置Toast在屏幕中的显示的位置
ToastAPI中有一个setGravity(int gravity, int xOffset, int yOffset)方法此方法可以完成对Toast显示位置的控制
第一个参数gravity可以使用Gravity类中提供的一些参数例如Gravity.TOP 、Gravity.LEFT、Gravity.RIGHT、Gravity.CENTER_HORIZONTAL.......
xOffset、yOffset 参数主要和Gracity实现的功能一样但是要比Gravity要强大。Gravity可以定义在屏幕的顶部、中间或是下部。
xOffset、yOffset 可以定义到屏幕的具体的位置,如果你不想他在设置中起作用都设置为0就可以了。在设置完Gravity的属性后 xOffset 负责水平位置的定位,
负值表示显示偏左,正值显示偏右。yOffset 负值表示偏上 正值表示偏下。
例如
[java] view plain copy print?
Toast toast = Toast.makeText(this, "test", Toast.LENGTH_SHORT)
toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0)
toast.show()
2、自定义Toast的布局,如果你不喜欢android系统自己带的Toast布局你完全可以自己定义一个显示的方式哦
ToastAPI中有一个setView(View view)方法
[java] view plain copy print?
Context context = getApplicationContext()
String msg = "test"
int duration = Toast.LENGTH_LONG
Toast toast = Toast.makeText(context, msg, duration)
toast.setGravity(Gravity.TOP, 0, 0)
LinearLayout ll = new LinearLayout(context)
ll.setOrientation(LinearLayout.VERTICAL)
Button button = new Button(context)
button.setText(msg)
int lHeight = LinearLayout.LayoutParams.FILL_PARENT
int lWidth = LinearLayout.LayoutParams.WRAP_CONTENT
ll.addView( button , new LinearLayout.LayoutParams(lHeight, lWidth))
ll.setPadding(40, 50, 0, 50)
toast.setView(ll)
toast.show()
这样就把button显示成了一个Toast,我是为了演示你可以自定义一个View
去显示你自己想显示的Toast
3、自定义显示Toast的显示时间 Toast的显示时间ToastAPI没有给出一个接口或是方法去设置和调用,
哪我们怎么去设置呢。通过查看Toast的源代码你可以发现一些东西下面是 Toast中show()方法的源代码
[java] view plain copy print?
/**
* Show the view for the specified duration.
*/
public void show() {
if (mNextView == null) {
throw new RuntimeException("setView must have been called")
}
INotificationManager service = getService()
String pkg = mContext.getPackageName()
TN tn = mTN
tn.mNextView = mNextView
try {
service.enqueueToast(pkg, tn, mDuration)
} catch (RemoteException e) {
// Empty
}
}
从中我们可以看到他把tn添加到了service的Toast处理队列中。哪我们是肯定是改不了的了 INotificationManager 是一个接口
[java] view plain copy print?
interface INotificationManager
{
void enqueueNotification(String pkg, int id, in Notification notification, inout int[] idReceived)
void cancelNotification(String pkg, int id)
void cancelAllNotifications(String pkg)
void enqueueToast(String pkg, ITransientNotification callback, int duration)
void cancelToast(String pkg, ITransientNotification callback)
}
它的实现类是 NotificationManagerService 通过查看这个类可以看出一点端倪
[java] view plain copy print?
public void enqueueToast(String pkg, ITransientNotification callback, int duration)
{
if (DBG) Slog.i(TAG, "enqueueToast pkg=" + pkg + " callback=" + callback + " duration=" + duration)
if (pkg == null || callback == null) {
Slog.e(TAG, "Not doing toast. pkg=" + pkg + " callback=" + callback)
return
}
final boolean isSystemToast = ("android".equals(pkg))
if (ENABLE_BLOCKED_TOASTS &&!isSystemToast &&!areNotificationsEnabledForPackageInt(pkg)) {
Slog.e(TAG, "Suppressing toast from package " + pkg + " by user request.")
return
}
synchronized (mToastQueue) {
int callingPid = Binder.getCallingPid()
long callingId = Binder.clearCallingIdentity()
try {
ToastRecord record
int index = indexOfToastLocked(pkg, callback)
// If it's already in the queue, we update it in place, we don't
// move it to the end of the queue.
if (index >= 0) {
record = mToastQueue.get(index)
record.update(duration)
} else {
// Limit the number of toasts that any given package except the android
// package can enqueue. Prevents DOS attacks and deals with leaks.
if (!isSystemToast) {
int count = 0
final int N = mToastQueue.size()
for (int i=0i<Ni++) {
final ToastRecord r = mToastQueue.get(i)
if (r.pkg.equals(pkg)) {
count++
if (count >= MAX_PACKAGE_NOTIFICATIONS) {
Slog.e(TAG, "Package has already posted " + count
+ " toasts. Not showing more. Package=" + pkg)
return
}
}
}
}
record = new ToastRecord(callingPid, pkg, callback, duration)
mToastQueue.add(record)
index = mToastQueue.size() - 1
keepProcessAliveLocked(callingPid)
}
// If it's at index 0, it's the current toast. It doesn't matter if it's
// new or just been updated. Call back and tell it to show itself.
// If the callback fails, this will remove it from the list, so don't
// assume that it's valid after this.
if (index == 0) {
showNextToastLocked()
}
} finally {
Binder.restoreCallingIdentity(callingId)
}
}
}
有点看不懂了。。。。。。。 其中的内嵌在Toast中的TN类可能实现了toast的显示 他其中有一些方法
[java] view plain copy print?
/**
* schedule handleShow into the right thread
*/
public void show() {
if (localLOGV) Log.v(TAG, "SHOW: " + this)
mHandler.post(mShow)
}
/**
* schedule handleHide into the right thread
*/
public void hide() {
if (localLOGV) Log.v(TAG, "HIDE: " + this)
mHandler.post(mHide)
}
可能控制Toast的显示我们可以试试
由于TN类是private的所以我们只能使用反射机制来做了
我们不能获得但是Toast类中有这个对象我们可以使用
[java] view plain copy print?
Field field = toast.getClass().getDeclaredField("mTN")
field.setAccessible(true)
Object obj = field.get(toast)
Method method = obj.getClass().getDeclaredMethod("show", null)
method1=obj.getClass().getDeclaredMethod("hide", null)
method.invoke(obj, null)
这样就使Toast一直显示了
要清除Toast的话只需要反射获得hide方法然后执行就可以了