如何通过创建MainActivity对象为ScannerOverlay指定扫描矩形宽高?
嘿,这事儿好办!咱们直接通过对象传参的方式给ScannerOverlay分配宽高就行,不用再从integer.xml里读了。我给你分文件一步步说清楚:
1. 改造ScannerOverlay.java
首先得给ScannerOverlay加个存储宽高的成员变量,然后提供构造方法或者setter方法来接收外部传入的数值,最后在onDraw里直接用这些值就行:
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.View; public class ScannerOverlay extends View { private int rectWidth; private int rectHeight; // 方案一:带宽高参数的构造方法,创建实例时直接传值 public ScannerOverlay(Context context, int rectWidth, int rectHeight) { super(context); this.rectWidth = rectWidth; this.rectHeight = rectHeight; } // 方案二:保留默认构造,用setter方法后续赋值 public ScannerOverlay(Context context) { super(context); } public void setRectDimensions(int rectWidth, int rectHeight) { this.rectWidth = rectWidth; this.rectHeight = rectHeight; invalidate(); // 必须调用这个方法,通知View重绘更新 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 确保宽高有效再绘制,避免空值问题 if (rectWidth <= 0 || rectHeight <= 0) return; // 举个居中绘制矩形的例子,你可以根据自己的需求调整位置 int left = (getWidth() - rectWidth) / 2; int top = (getHeight() - rectHeight) / 2; int right = left + rectWidth; int bottom = top + rectHeight; Paint paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5); canvas.drawRect(left, top, right, bottom, paint); } }
2. 修改MainActivity.java
这里你可以选择动态创建ScannerOverlay实例或者从XML引用后赋值,两种方式都给你列出来:
import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.widget.LinearLayout; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 先定义你想要的宽高,建议转成px适配不同设备 int desiredWidth = dpToPx(600); // 600dp转px int desiredHeight = dpToPx(400); // 400dp转px // ------------------- 方式一:动态创建并添加到布局 ------------------- ScannerOverlay scannerOverlay = new ScannerOverlay(this, desiredWidth, desiredHeight); // 获取布局容器(需要在activity_main里加个容器,比如LinearLayout) LinearLayout container = findViewById(R.id.overlay_container); container.addView(scannerOverlay); // ------------------- 方式二:从XML引用后用setter赋值 ------------------- // ScannerOverlay scannerOverlay = findViewById(R.id.scanner_overlay); // scannerOverlay.setRectDimensions(desiredWidth, desiredHeight); } // 工具方法:dp转px,适配不同分辨率设备 private int dpToPx(int dp) { float density = getResources().getDisplayMetrics().density; return Math.round(dp * density); } }
3. 调整activity_main.xml
根据你选的方式来修改布局:
如果用动态创建的方式:
需要加一个容器来放ScannerOverlay:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/overlay_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 这里可以放你的其他控件,比如扫码预览的SurfaceView --> </LinearLayout>
如果用XML引用的方式:
直接把ScannerOverlay写进布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 其他控件,比如扫码预览 --> <com.yourpackage.ScannerOverlay android:id="@+id/scanner_overlay" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
小提示
- 记得把
com.yourpackage换成你自己的包名,不然XML里会报错 - 如果用setter方法赋值,一定要调用
invalidate(),不然View不会重绘更新 - 用dp转px的方式能让你的矩形在不同分辨率的设备上显示效果一致
内容的提问来源于stack exchange,提问作者matchs
相关产品推荐
相关产品推荐

