我应该使用新的 activity 还是片段来扫描条形码?
Should I use new activity or a fragment for scanning a barcode?
我有一个 activity 如果用户应该能够通过书写或使用条形码扫描仪通过单击编辑文本旁边的按钮来输入 2 个参数。
对于扫描,我将使用 zxing,因为我可以用它找到很多可用的示例。扫描后,应将扫描值写入用户的编辑框中。
我的问题是我不知道应该使用片段还是新的 activity,因为我需要与它通信。
一个片段是有意义的,因为我想用 camera/scanner 覆盖整个屏幕,但是是否建议在 2 个整个屏幕片段之间切换?
如果我应该使用片段,对于这种情况最好的方法是什么?
xzing 片段示例:
public class FullScannerActivity extends BaseScannerActivity implements MessageDialogFragment.MessageDialogListener,
ZXingScannerView.ResultHandler, FormatSelectorDialogFragment.FormatSelectorDialogListener,
CameraSelectorDialogFragment.CameraSelectorDialogListener {
private static final String FLASH_STATE = "FLASH_STATE";
private static final String AUTO_FOCUS_STATE = "AUTO_FOCUS_STATE";
private static final String SELECTED_FORMATS = "SELECTED_FORMATS";
private static final String CAMERA_ID = "CAMERA_ID";
private ZXingScannerView mScannerView;
private boolean mFlash;
private boolean mAutoFocus;
private ArrayList<Integer> mSelectedIndices;
private int mCameraId = -1;
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
if(state != null) {
mFlash = state.getBoolean(FLASH_STATE, false);
mAutoFocus = state.getBoolean(AUTO_FOCUS_STATE, true);
mSelectedIndices = state.getIntegerArrayList(SELECTED_FORMATS);
mCameraId = state.getInt(CAMERA_ID, -1);
} else {
mFlash = false;
mAutoFocus = true;
mSelectedIndices = null;
mCameraId = -1;
}
setContentView(R.layout.activity_simple_scanner);
setupToolbar();
ViewGroup contentFrame = (ViewGroup) findViewById(R.id.content_frame);
mScannerView = new ZXingScannerView(this);
setupFormats();
contentFrame.addView(mScannerView);
}
@Override
public void onResume() {
super.onResume();
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(FLASH_STATE, mFlash);
outState.putBoolean(AUTO_FOCUS_STATE, mAutoFocus);
outState.putIntegerArrayList(SELECTED_FORMATS, mSelectedIndices);
outState.putInt(CAMERA_ID, mCameraId);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem menuItem;
if(mFlash) {
menuItem = menu.add(Menu.NONE, R.id.menu_flash, 0, R.string.flash_on);
} else {
menuItem = menu.add(Menu.NONE, R.id.menu_flash, 0, R.string.flash_off);
}
MenuItemCompat.setShowAsAction(menuItem, MenuItem.SHOW_AS_ACTION_NEVER);
if(mAutoFocus) {
menuItem = menu.add(Menu.NONE, R.id.menu_auto_focus, 0, R.string.auto_focus_on);
} else {
menuItem = menu.add(Menu.NONE, R.id.menu_auto_focus, 0, R.string.auto_focus_off);
}
MenuItemCompat.setShowAsAction(menuItem, MenuItem.SHOW_AS_ACTION_NEVER);
menuItem = menu.add(Menu.NONE, R.id.menu_formats, 0, R.string.formats);
MenuItemCompat.setShowAsAction(menuItem, MenuItem.SHOW_AS_ACTION_NEVER);
menuItem = menu.add(Menu.NONE, R.id.menu_camera_selector, 0, R.string.select_camera);
MenuItemCompat.setShowAsAction(menuItem, MenuItem.SHOW_AS_ACTION_NEVER);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.menu_flash:
mFlash = !mFlash;
if(mFlash) {
item.setTitle(R.string.flash_on);
} else {
item.setTitle(R.string.flash_off);
}
mScannerView.setFlash(mFlash);
return true;
case R.id.menu_auto_focus:
mAutoFocus = !mAutoFocus;
if(mAutoFocus) {
item.setTitle(R.string.auto_focus_on);
} else {
item.setTitle(R.string.auto_focus_off);
}
mScannerView.setAutoFocus(mAutoFocus);
return true;
case R.id.menu_formats:
DialogFragment fragment = FormatSelectorDialogFragment.newInstance(this, mSelectedIndices);
fragment.show(getSupportFragmentManager(), "format_selector");
return true;
case R.id.menu_camera_selector:
mScannerView.stopCamera();
DialogFragment cFragment = CameraSelectorDialogFragment.newInstance(this, mCameraId);
cFragment.show(getSupportFragmentManager(), "camera_selector");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void handleResult(Result rawResult) {
try {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (Exception e) {}
showMessageDialog("Contents = " + rawResult.getText() + ", Format = " + rawResult.getBarcodeFormat().toString());
}
public void showMessageDialog(String message) {
DialogFragment fragment = MessageDialogFragment.newInstance("Scan Results", message, this);
fragment.show(getSupportFragmentManager(), "scan_results");
}
public void closeMessageDialog() {
closeDialog("scan_results");
}
public void closeFormatsDialog() {
closeDialog("format_selector");
}
public void closeDialog(String dialogName) {
FragmentManager fragmentManager = getSupportFragmentManager();
DialogFragment fragment = (DialogFragment) fragmentManager.findFragmentByTag(dialogName);
if(fragment != null) {
fragment.dismiss();
}
}
@Override
public void onDialogPositiveClick(DialogFragment dialog) {
// Resume the camera
mScannerView.resumeCameraPreview(this);
}
@Override
public void onFormatsSaved(ArrayList<Integer> selectedIndices) {
mSelectedIndices = selectedIndices;
setupFormats();
}
@Override
public void onCameraSelected(int cameraId) {
mCameraId = cameraId;
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
}
public void setupFormats() {
List<BarcodeFormat> formats = new ArrayList<BarcodeFormat>();
if(mSelectedIndices == null || mSelectedIndices.isEmpty()) {
mSelectedIndices = new ArrayList<Integer>();
for(int i = 0; i < ZXingScannerView.ALL_FORMATS.size(); i++) {
mSelectedIndices.add(i);
}
}
for(int index : mSelectedIndices) {
formats.add(ZXingScannerView.ALL_FORMATS.get(index));
}
if(mScannerView != null) {
mScannerView.setFormats(formats);
}
}
@Override
public void onPause() {
super.onPause();
mScannerView.stopCamera();
closeMessageDialog();
closeFormatsDialog();
}
xml:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="com.example.registerbutton.FullScannerFragment"
android:id="@+id/scanner_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_gravity="top"
android:minHeight="?attr/actionBarSize"
android:background="@color/actionbar_opacity"
app:theme="@style/TransparentToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
我建议创建一个新的 Activity
而不是 Fragment
。您可以发送数据,也可以从中接收数据。
要发送数据,您可以使用 startActivityForResult()
和可选的 intent.putData()
。
为了接收数据,您可以覆盖 onActivityResult()
。
我有一个 activity 如果用户应该能够通过书写或使用条形码扫描仪通过单击编辑文本旁边的按钮来输入 2 个参数。
对于扫描,我将使用 zxing,因为我可以用它找到很多可用的示例。扫描后,应将扫描值写入用户的编辑框中。
我的问题是我不知道应该使用片段还是新的 activity,因为我需要与它通信。
一个片段是有意义的,因为我想用 camera/scanner 覆盖整个屏幕,但是是否建议在 2 个整个屏幕片段之间切换?
如果我应该使用片段,对于这种情况最好的方法是什么?
xzing 片段示例:
public class FullScannerActivity extends BaseScannerActivity implements MessageDialogFragment.MessageDialogListener,
ZXingScannerView.ResultHandler, FormatSelectorDialogFragment.FormatSelectorDialogListener,
CameraSelectorDialogFragment.CameraSelectorDialogListener {
private static final String FLASH_STATE = "FLASH_STATE";
private static final String AUTO_FOCUS_STATE = "AUTO_FOCUS_STATE";
private static final String SELECTED_FORMATS = "SELECTED_FORMATS";
private static final String CAMERA_ID = "CAMERA_ID";
private ZXingScannerView mScannerView;
private boolean mFlash;
private boolean mAutoFocus;
private ArrayList<Integer> mSelectedIndices;
private int mCameraId = -1;
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
if(state != null) {
mFlash = state.getBoolean(FLASH_STATE, false);
mAutoFocus = state.getBoolean(AUTO_FOCUS_STATE, true);
mSelectedIndices = state.getIntegerArrayList(SELECTED_FORMATS);
mCameraId = state.getInt(CAMERA_ID, -1);
} else {
mFlash = false;
mAutoFocus = true;
mSelectedIndices = null;
mCameraId = -1;
}
setContentView(R.layout.activity_simple_scanner);
setupToolbar();
ViewGroup contentFrame = (ViewGroup) findViewById(R.id.content_frame);
mScannerView = new ZXingScannerView(this);
setupFormats();
contentFrame.addView(mScannerView);
}
@Override
public void onResume() {
super.onResume();
mScannerView.setResultHandler(this);
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(FLASH_STATE, mFlash);
outState.putBoolean(AUTO_FOCUS_STATE, mAutoFocus);
outState.putIntegerArrayList(SELECTED_FORMATS, mSelectedIndices);
outState.putInt(CAMERA_ID, mCameraId);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem menuItem;
if(mFlash) {
menuItem = menu.add(Menu.NONE, R.id.menu_flash, 0, R.string.flash_on);
} else {
menuItem = menu.add(Menu.NONE, R.id.menu_flash, 0, R.string.flash_off);
}
MenuItemCompat.setShowAsAction(menuItem, MenuItem.SHOW_AS_ACTION_NEVER);
if(mAutoFocus) {
menuItem = menu.add(Menu.NONE, R.id.menu_auto_focus, 0, R.string.auto_focus_on);
} else {
menuItem = menu.add(Menu.NONE, R.id.menu_auto_focus, 0, R.string.auto_focus_off);
}
MenuItemCompat.setShowAsAction(menuItem, MenuItem.SHOW_AS_ACTION_NEVER);
menuItem = menu.add(Menu.NONE, R.id.menu_formats, 0, R.string.formats);
MenuItemCompat.setShowAsAction(menuItem, MenuItem.SHOW_AS_ACTION_NEVER);
menuItem = menu.add(Menu.NONE, R.id.menu_camera_selector, 0, R.string.select_camera);
MenuItemCompat.setShowAsAction(menuItem, MenuItem.SHOW_AS_ACTION_NEVER);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.menu_flash:
mFlash = !mFlash;
if(mFlash) {
item.setTitle(R.string.flash_on);
} else {
item.setTitle(R.string.flash_off);
}
mScannerView.setFlash(mFlash);
return true;
case R.id.menu_auto_focus:
mAutoFocus = !mAutoFocus;
if(mAutoFocus) {
item.setTitle(R.string.auto_focus_on);
} else {
item.setTitle(R.string.auto_focus_off);
}
mScannerView.setAutoFocus(mAutoFocus);
return true;
case R.id.menu_formats:
DialogFragment fragment = FormatSelectorDialogFragment.newInstance(this, mSelectedIndices);
fragment.show(getSupportFragmentManager(), "format_selector");
return true;
case R.id.menu_camera_selector:
mScannerView.stopCamera();
DialogFragment cFragment = CameraSelectorDialogFragment.newInstance(this, mCameraId);
cFragment.show(getSupportFragmentManager(), "camera_selector");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void handleResult(Result rawResult) {
try {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (Exception e) {}
showMessageDialog("Contents = " + rawResult.getText() + ", Format = " + rawResult.getBarcodeFormat().toString());
}
public void showMessageDialog(String message) {
DialogFragment fragment = MessageDialogFragment.newInstance("Scan Results", message, this);
fragment.show(getSupportFragmentManager(), "scan_results");
}
public void closeMessageDialog() {
closeDialog("scan_results");
}
public void closeFormatsDialog() {
closeDialog("format_selector");
}
public void closeDialog(String dialogName) {
FragmentManager fragmentManager = getSupportFragmentManager();
DialogFragment fragment = (DialogFragment) fragmentManager.findFragmentByTag(dialogName);
if(fragment != null) {
fragment.dismiss();
}
}
@Override
public void onDialogPositiveClick(DialogFragment dialog) {
// Resume the camera
mScannerView.resumeCameraPreview(this);
}
@Override
public void onFormatsSaved(ArrayList<Integer> selectedIndices) {
mSelectedIndices = selectedIndices;
setupFormats();
}
@Override
public void onCameraSelected(int cameraId) {
mCameraId = cameraId;
mScannerView.startCamera(mCameraId);
mScannerView.setFlash(mFlash);
mScannerView.setAutoFocus(mAutoFocus);
}
public void setupFormats() {
List<BarcodeFormat> formats = new ArrayList<BarcodeFormat>();
if(mSelectedIndices == null || mSelectedIndices.isEmpty()) {
mSelectedIndices = new ArrayList<Integer>();
for(int i = 0; i < ZXingScannerView.ALL_FORMATS.size(); i++) {
mSelectedIndices.add(i);
}
}
for(int index : mSelectedIndices) {
formats.add(ZXingScannerView.ALL_FORMATS.get(index));
}
if(mScannerView != null) {
mScannerView.setFormats(formats);
}
}
@Override
public void onPause() {
super.onPause();
mScannerView.stopCamera();
closeMessageDialog();
closeFormatsDialog();
}
xml:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="com.example.registerbutton.FullScannerFragment"
android:id="@+id/scanner_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_gravity="top"
android:minHeight="?attr/actionBarSize"
android:background="@color/actionbar_opacity"
app:theme="@style/TransparentToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
我建议创建一个新的 Activity
而不是 Fragment
。您可以发送数据,也可以从中接收数据。
要发送数据,您可以使用 startActivityForResult()
和可选的 intent.putData()
。
为了接收数据,您可以覆盖 onActivityResult()
。