55-Android之修改Toast的显示时长

55-Android之修改Toast的显示时长

平台:SRPD Android10 SC9832E

在系统中,输入法切换的提示,我使用的是Toast的来实现的。

后续客户测试反映,输入法切换的提示显示太慢,要求改进。

我因此针对输入法的Toast的显示,增加了一个Toast.LENGTH_INPUT属性。

frameworks/base/core/java/android/widget/Toast.java

@IntDef(prefix = { "LENGTH_" }, value = {
     		LENGTH_SHORT,
            LENGTH_LONG,
            LENGTH_INPUT // TODO 添加
})
@Retention(RetentionPolicy.SOURCE)
public @interface Duration {}

public static final int LENGTH_INPUT = 2;  // TODO 添加

frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java 

@GuardedBy("mToastQueue")
private void scheduleDurationReachedLocked(ToastRecord r){
    mHandler.removeCallbacksAndMessages(r);
    Message m = Message.obtain(mHandler, MESSAGE_DURATION_REACHED, r);
    // TODO 此处修改 @{
    // int delay = r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY;
    int delay = r.duration == Toast.LENGTH_LONG ? LONG_DELAY : (r.duration == Toast.LENGTH_INPUT ? 800 : SHORT_DELAY);
    // @}
    // Accessibility users may need longer timeout duration. This api compares original delay
    // with user's preference and return longer one. It returns original delay if there's no
    // preference.
    delay = mAccessibilityManager.getRecommendedTimeoutMillis(delay,
            AccessibilityManager.FLAG_CONTENT_TEXT);
    mHandler.sendMessageDelayed(m, delay);
}

如果需要修改Toast的Toast.LENGTH_SHORT和Toast. LENGTH_LONG的默认时长,请修改NotificationManagerService中LONG_DELAY和SHORT_DELAY常量的值:

frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java 

static final int LONG_DELAY = PhoneWindowManager.TOAST_WINDOW_TIMEOUT;
static final int SHORT_DELAY = 2000; // 2 seconds,TODO 修改该值


frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

public static final int TOAST_WINDOW_TIMEOUT = 3500; // 3.5 seconds, TODO 修改该值
代码实现 playmouse.java package com.example.playmouse; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import java.util.Random; public class playmouse extends AppCompatActivity { /************1.定义变量、对象、洞穴坐标******************/ private int i=0;//记录打到的地鼠个数 private ImageView mouse;//定义 mouse 对象 private TextView info1; //定义 info1 对象(用于查看洞穴坐标) private Handler handler;//声明一个 Handler 对象 public int[][] position=new int[][]{ {277, 200}, {535, 200}, {832, 200}, {1067,200}, {1328, 200}, {285, 360}, {645, 360}, {1014,360}, {1348, 360},{319, 600},{764, 600},{1229,600} };//创建一个表示地鼠位置的数组 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置不显示顶部栏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//设置横屏模式 /************2.绑定控件*****************/ mouse = (ImageView) findViewById(R.id.imageView1); info1 = findViewById(R.id.info); /************获取洞穴位置*****************/ //通过 logcat 查看 【注】:getRawY():触摸点距离屏幕上方的长度(此长度包括程序项目名栏的) info1.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: float x = event.getRawX(); float y = event.getRawY(); Log.i("x:" + x, "y:" + y); break; default: break; } return false; } }); /************3.实现地鼠随机出现*****************/ //创建 Handler 消息处理机制 handler = new Handler() { @Override public void handleMessage(@NonNull Message msg) { //需要处理的消息 int index; if (msg.what == 0x101) { index = msg.arg1;//// 获取位置索引值 mouse.setX(position[index][0]);//设置 X 轴坐标 mouse.setY(position[index][1]);//设置 Y 轴坐标(原点为屏幕左上角(不包括程序名称栏)) mouse.setVisibility(View.VISIBLE);//设置地鼠显示 } super.handleMessage(msg); } }; // 创建线程 Thread t = new Thread(new Runnable() { @Override public void run() { int index = 0;// 定义一个记录地鼠位置的索引值 while (!Thread.currentThread().isInterrupted()) { index = new Random().nextInt(position.length);// 产生一个随机整数(范围:0<=index<数组长度) Message m = handler.obtainMessage();//创建消息对象 m.what = 0x101;//设置消息标志 m.arg1 = index;// 保存地鼠标位置的索引值 handler.sendMessage(m);// 发送消息通知 Handler 处理 try { Thread.sleep(new Random().nextInt(500) + 500); // 休眠一段时间 } catch (InterruptedException e) { e.printStackTrace(); } } } }); t.start(); /************4.实现点击地鼠后的事件:让地鼠不显示&显示消息*****************/ // 添加触摸 mouse 后的事件 mouse.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { v.setVisibility(View.INVISIBLE);//设置地鼠不显示 i++; Toast.makeText(playmouse.this, "打到[ " + i + " ]只地鼠!", Toast.LENGTH_SHORT).show(); // 显示消息提示框 return false; } }); }} 一键获取完整项目代码 java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 activity_main.xml <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fl" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/background" > <ImageView android:id="@+id/imageView1" android:layout_width="72dp" android:layout_height="72dp" android:src="@drawable/mouse1" /> <TextView android:id="@+id/info" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </FrameLayout> 一键获取完整项目代码 java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 styles.xml(把顶部通知栏去掉) <resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> </resources> 一键获取完整项目代码 java,能否详细的写出步骤,以及手把手教学
最新发布
11-13
<think> 这是一个Android打地鼠游戏的项目代码,主要包含一个Activity(playmouse.java)和布局文件(activity_main.xml)以及样式文件(styles.xml)的代码。下面我将详细解释代码,并给出实现步骤。 ### 1. 项目结构 - **playmouse.java**:主Activity,包含游戏逻辑。 - **activity_main.xml**:布局文件,定义游戏界面。 - **styles.xml**:样式文件,用于设置无标题栏。 ### 2. 代码解释 #### playmouse.java ```java package com.example.playmouse; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import java.util.Random; public class playmouse extends AppCompatActivity { private int i = 0; // 记录打到的地鼠个数 private ImageView mouse; // 地鼠ImageView private TextView info1; // 用于查看洞穴坐标的TextView(调试用) private Handler handler; // 用于处理消息的Handler // 地鼠出现的12个位置的坐标数组 public int[][] position = new int[][]{ {277, 200}, {535, 200}, {832, 200}, {1067,200}, {1328, 200}, {285, 360}, {645, 360}, {1014,360}, {1348, 360}, {319, 600}, {764, 600}, {1229,600} }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 设置全屏 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 设置横屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // 绑定控件 mouse = (ImageView) findViewById(R.id.imageView1); info1 = findViewById(R.id.info); // 获取洞穴位置(调试用,通过触摸屏幕打印坐标) info1.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: float x = event.getRawX(); float y = event.getRawY(); Log.i("坐标", "x:" + x + ", y:" + y); break; default: break; } return false; } }); // 创建Handler,用于处理地鼠位置更新的消息 handler = new Handler() { @Override public void handleMessage(@NonNull Message msg) { if (msg.what == 0x101) { int index = msg.arg1; // 获取位置索引 // 设置地鼠的位置 mouse.setX(position[index][0]); mouse.setY(position[index][1]); mouse.setVisibility(View.VISIBLE); // 显示地鼠 } super.handleMessage(msg); } }; // 创建一个线程,用于随机生成地鼠位置 Thread t = new Thread(new Runnable() { @Override public void run() { int index = 0; while (!Thread.currentThread().isInterrupted()) { // 随机生成一个位置索引 index = new Random().nextInt(position.length); Message m = handler.obtainMessage(); m.what = 0x101; // 消息标识 m.arg1 = index; // 传递索引 handler.sendMessage(m); // 发送消息 try { // 随机休眠500-1000毫 Thread.sleep(new Random().nextInt(500) + 500); } catch (InterruptedException e) { e.printStackTrace(); } } } }); t.start(); // 启动线程 // 设置地鼠的触摸事件 mouse.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { v.setVisibility(View.INVISIBLE); // 点击后隐藏地鼠 i++; // 计数增加 Toast.makeText(playmouse.this, "打到[ " + i + " ]只地鼠!", Toast.LENGTH_SHORT).show(); return false; } }); } } ``` #### activity_main.xml ```xml <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fl" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/background" > <!-- 设置背景图片 --> <!-- 地鼠ImageView,初始位置不重要,因为代码中会动态设置 --> <ImageView android:id="@+id/imageView1" android:layout_width="72dp" android:layout_height="72dp" android:src="@drawable/mouse1" /> <!-- 用于调试的TextView,覆盖全屏,用于获取坐标 --> <TextView android:id="@+id/info" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </FrameLayout> ``` #### styles.xml ```xml <resources> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> </resources> ``` ### 3. 实现步骤 1. **创建Android项目**:使用Android Studio创建一个新项目,选择Empty Activity。 2. **准备资源**:将背景图片(background.png)和地鼠图片(mouse1.png)放入res/drawable目录。 3. **修改布局文件**:创建activity_main.xml,使用FrameLayout,包含一个ImageView(地鼠)和一个TextView(用于调试坐标)。 4. **修改样式**:在styles.xml中设置无标题栏(NoActionBar)。 5. **编写Activity代码**:在MainActivity(这里重命名为playmouse)中编写游戏逻辑。 6. **运行测试**:在模拟器或真机上运行。 ### 4. 关键点说明 - **全屏和横屏设置**:在onCreate中设置全屏和横屏模式。 - **坐标获取**:通过TextView的触摸事件获取坐标,用于确定地鼠位置(调试用)。 - **Handler机制**:用于在子线程中更新UI,子线程随机选择位置,通过Handler发送消息给主线程更新地鼠位置。 - **地鼠触摸事件**:点击地鼠后,地鼠消失,并显示打到的地鼠数量。 ### 5. 注意事项 - 坐标数组`position`中的坐标是根据具体屏幕尺寸调试得到的,不同设备可能需要调整。 - 调试用的TextView在最终版本中可以隐藏或移除。 - 地鼠图片的大小(72dp)可能需要根据实际效果调整。 ### 6. 相关资源 - 背景图片(background.png):需要一张背景图,例如有多个洞穴的图片。 - 地鼠图片(mouse1.png):地鼠的图片。 ### 7. 完整项目代码获取 上述代码已经给出,但需要结合资源文件。如果需要完整项目,请按照上述步骤创建,并添加资源图片。 ### 相关问题 §§相关问题§§: 1. 如何在Android中实现全屏显示? 2. Handler在Android中的作用是什么?它是如何工作的? 3. 如何获取触摸事件的坐标? 4. 在Android中如何设置横屏模式? </think>### 打地鼠游戏实现详解与手把手教学 这是一个基于Android平台的打地鼠游戏实现。下面我将详细解释代码,并提供完整的实现步骤: #### 核心实现原理 1. **全屏横屏显示**:设置全屏和横屏模式 2. **随机位置生成**:使用线程随机选择洞穴位置 3. **Handler消息机制**:用于更新UI线程的地鼠位置 4. **触摸事件处理**:检测用户点击地鼠的动作 ### 完整实现步骤(手把手教学) #### 步骤1:创建Android项目 1. 在Android Studio中创建新项目 2. 选择"Empty Activity"模板 3. 设置包名为`com.example.playmouse` #### 步骤2:准备资源文件 1. 在`res/drawable`文件夹中添加: - `background.png`(游戏背景图) - `mouse1.png`(地鼠图片) 2. 在`res/layout`中创建`activity_main.xml` ```xml <!-- res/layout/activity_main.xml --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fl" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/background"> <ImageView android:id="@+id/imageView1" android:layout_width="72dp" android:layout_height="72dp" android:src="@drawable/mouse1"/> <TextView android:id="@+id/info" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </FrameLayout> ``` #### 步骤3:修改样式文件 ```xml <!-- res/values/styles.xml --> <resources> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> </resources> ``` #### 步骤4:实现主游戏逻辑 ```java // src/main/java/com/example/playmouse/PlayMouseActivity.java package com.example.playmouse; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import java.util.Random; public class PlayMouseActivity extends AppCompatActivity { private int score = 0; // 分数计数器 private ImageView mouse; // 地鼠ImageView private Handler handler; // 消息处理器 // 地鼠位置坐标数组(12个位置) private final int[][] position = { {277, 200}, {535, 200}, {832, 200}, {1067,200}, {1328, 200}, {285, 360}, {645, 360}, {1014,360}, {1348, 360}, {319, 600}, {764, 600}, {1229,600} }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 设置全屏显示 getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN ); // 设置横屏模式 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // 绑定UI元素 mouse = findViewById(R.id.imageView1); TextView info = findViewById(R.id.info); // 调试用:获取屏幕坐标 info.setOnTouchListener((v, event) -> { if (event.getAction() == MotionEvent.ACTION_DOWN) { float x = event.getRawX(); float y = event.getRawY(); Log.i("坐标", "X: " + x + ", Y: " + y); } return false; }); // 初始化Handler handler = new Handler(getMainLooper()) { @Override public void handleMessage(Message msg) { if (msg.what == 0x101) { int index = msg.arg1; mouse.setX(position[index][0]); mouse.setY(position[index][1]); mouse.setVisibility(View.VISIBLE); } } }; // 启动地鼠生成线程 new Thread(() -> { while (!Thread.interrupted()) { int index = new Random().nextInt(position.length); Message msg = handler.obtainMessage(); msg.what = 0x101; msg.arg1 = index; handler.sendMessage(msg); try { Thread.sleep(new Random().nextInt(500) + 500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }).start(); // 设置地鼠点击事件 mouse.setOnTouchListener((v, event) -> { if (event.getAction() == MotionEvent.ACTION_DOWN) { v.setVisibility(View.INVISIBLE); score++; Toast.makeText(PlayMouseActivity.this, "打到[" + score + "]只地鼠!", Toast.LENGTH_SHORT).show(); } return true; }); } } ``` #### 步骤5:修改AndroidManifest.xml ```xml <!-- AndroidManifest.xml --> <application android:theme="@style/AppTheme"> <activity android:name=".PlayMouseActivity" android:screenOrientation="landscape"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> ``` ### 代码详细解释 1. **初始化设置**: - 全屏显示:`FLAG_FULLSCREEN` - 横屏模式:`SCREEN_ORIENTATION_LANDSCAPE` - 无标题栏:`NoActionBar`主题 2. **坐标系统**: - `position`数组存储12个洞穴的(x,y)坐标 - 使用`getRawX()`和`getRawY()`获取绝对坐标 3. **Handler消息机制**: - 子线程生成随机位置索引(0-11) - 发送消息`what=0x101`给主线程 - 主线程更新地鼠位置 4. **地鼠生成逻辑**: - 随机休眠500-1000毫 - 使用`setX()`和`setY()`设置位置 - `setVisibility(View.VISIBLE)`显示地鼠 5. **点击事件处理**: - 点击时设置地鼠不可见 - 分数计数器+1 - 显示Toast提示 ### 优化建议 1. **游戏难度控制**: ```java // 动态调整出现速度 int speed = 1000 - (score * 10); if (speed < 200) speed = 200; Thread.sleep(speed); ``` 2. **添加游戏计时**: ```java // 60倒计时 new CountDownTimer(60000, 1000) { public void onTick(long millisUntilFinished) { timerText.setText("时间: " + millisUntilFinished/1000); } public void onFinish() { Toast.makeText(GameActivity.this, "游戏结束! 分数: " + score, Toast.LENGTH_LONG).show(); } }.start(); ``` 3. **添加音效**: ```java // 点击时播放音效 MediaPlayer.create(this, R.raw.hit_sound).start(); ``` ### 常见问题解决 1. **坐标不准问题**: - 不同设备分辨率不同 - 解决方案:使用相对坐标 ```java // 获取屏幕尺寸 DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int screenWidth = metrics.widthPixels; int screenHeight = metrics.heightPixels; // 计算相对位置 position[0][0] = (int)(screenWidth * 0.2); position[0][1] = (int)(screenHeight * 0.15); ``` 2. **内存泄漏问题**: - 在`onDestroy()`中停止线程 ```java @Override protected void onDestroy() { handler.removeCallbacksAndMessages(null); super.onDestroy(); } ``` 3. **点击响应问题**: - 确保地鼠图片有透明背景 - 使用`setOnTouchListener`替代`setOnClickListener` ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值