Demo 工程迁移到 APIJSON-Demo 项目;APIJSONORM 和 APIJSONFramework 迁移到最外层;调整文档中的链接
This commit is contained in:
parent
aa45fc0304
commit
91255dab8b
7
APIJSON-Android/APIJSONApp/.gitignore
vendored
7
APIJSON-Android/APIJSONApp/.gitignore
vendored
@ -1,7 +0,0 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
.idea
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
@ -1 +0,0 @@
|
||||
/build
|
@ -1,25 +0,0 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.0'
|
||||
defaultConfig {
|
||||
minSdkVersion 20
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
productFlavors {
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
Binary file not shown.
@ -1,17 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /Users/Tommy/Library/Android/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
@ -1,13 +0,0 @@
|
||||
package com.ericssonlabs;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.ericssonlabs"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="10" />
|
||||
|
||||
<!-- 复制粘贴到你的工程的AndroidManifest.xml内对应位置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -->
|
||||
|
||||
|
||||
<!-- 需要的权限和功能 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -->
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.FLASHLIGHT" />
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||
<!-- 需要的权限和功能 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||
|
||||
<!-- 复制粘贴到你的工程的AndroidManifest.xml内对应位置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||
|
||||
</manifest>
|
@ -1,243 +0,0 @@
|
||||
package com.zxing.activity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Vector;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.MediaPlayer.OnCompletionListener;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Vibrator;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceHolder.Callback;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.Window;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.ericssonlabs.R;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.Result;
|
||||
import com.zxing.camera.CameraManager;
|
||||
import com.zxing.decoding.CaptureActivityHandler;
|
||||
import com.zxing.decoding.CaptureActivityHandler.DecodeCallback;
|
||||
import com.zxing.decoding.InactivityTimer;
|
||||
import com.zxing.view.ViewfinderView;
|
||||
/**
|
||||
* Initial the camera
|
||||
* @author Ryan.Tang
|
||||
* @modifier Lemon
|
||||
* @use extends CaptureActivity并且在setContentView方法后调用init方法
|
||||
*/
|
||||
public abstract class CaptureActivity extends Activity implements Callback, DecodeCallback {
|
||||
// private static final String TAG = "CaptureActivity";
|
||||
|
||||
protected Activity context;
|
||||
protected SurfaceView surfaceView;
|
||||
protected ViewfinderView viewfinderView;
|
||||
/**初始化,必须在setContentView之后
|
||||
* @param context
|
||||
* @param viewfinderView
|
||||
*/
|
||||
protected void init(Activity context, SurfaceView surfaceView, ViewfinderView viewfinderView) {
|
||||
this.context = context;
|
||||
this.surfaceView = surfaceView;
|
||||
this.viewfinderView = viewfinderView;
|
||||
|
||||
CameraManager.init(getApplication());
|
||||
|
||||
hasSurface = false;
|
||||
inactivityTimer = new InactivityTimer(this);
|
||||
}
|
||||
|
||||
private boolean isOn = false;
|
||||
protected final boolean isOn() {
|
||||
return isOn;
|
||||
}
|
||||
/**打开或关闭闪关灯
|
||||
* @param open
|
||||
*/
|
||||
protected void switchLight(boolean on) {
|
||||
if (on == isOn()) {
|
||||
return;
|
||||
}
|
||||
isOn = CameraManager.get().switchLight(on);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
}
|
||||
|
||||
|
||||
private CaptureActivityHandler handler;
|
||||
private boolean hasSurface;
|
||||
private Vector<BarcodeFormat> decodeFormats;
|
||||
private String characterSet;
|
||||
private InactivityTimer inactivityTimer;
|
||||
private MediaPlayer mediaPlayer;
|
||||
private boolean playBeep;
|
||||
private static final float BEEP_VOLUME = 0.10f;
|
||||
private boolean vibrate;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
SurfaceHolder surfaceHolder = surfaceView.getHolder();
|
||||
if (hasSurface) {
|
||||
initCamera(surfaceHolder);
|
||||
} else {
|
||||
surfaceHolder.addCallback(this);
|
||||
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
||||
}
|
||||
decodeFormats = null;
|
||||
characterSet = null;
|
||||
|
||||
playBeep = true;
|
||||
AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
|
||||
if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
|
||||
playBeep = false;
|
||||
}
|
||||
initBeepSound();
|
||||
vibrate = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (handler != null) {
|
||||
handler.quitSynchronously();
|
||||
handler = null;
|
||||
}
|
||||
isOn = false;
|
||||
CameraManager.get().closeDriver();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
inactivityTimer.shutdown();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
public static final String RESULT_QRCODE_STRING = "RESULT_QRCODE_STRING";
|
||||
/**
|
||||
* Handler scan result
|
||||
* @param result
|
||||
* @param barcode
|
||||
*/
|
||||
public void handleDecode(Result result, Bitmap barcode) {
|
||||
inactivityTimer.onActivity();
|
||||
playBeepSoundAndVibrate();
|
||||
String resultString = result.getText();
|
||||
//FIXME
|
||||
if (resultString.equals("")) {
|
||||
Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
setResult(RESULT_OK, new Intent().putExtra(RESULT_QRCODE_STRING, resultString));
|
||||
finish();
|
||||
}
|
||||
|
||||
private void initCamera(SurfaceHolder surfaceHolder) {
|
||||
try {
|
||||
CameraManager.get().openDriver(surfaceHolder);
|
||||
} catch (IOException ioe) {
|
||||
return;
|
||||
} catch (RuntimeException e) {
|
||||
return;
|
||||
}
|
||||
if (handler == null) {
|
||||
handler = new CaptureActivityHandler(this, decodeFormats,
|
||||
characterSet, viewfinderView, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawViewfinder() {
|
||||
viewfinderView.drawViewfinder();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width,
|
||||
int height) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
if (!hasSurface) {
|
||||
hasSurface = true;
|
||||
initCamera(holder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
hasSurface = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public Handler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
private void initBeepSound() {
|
||||
if (playBeep && mediaPlayer == null) {
|
||||
// The volume on STREAM_SYSTEM is not adjustable, and users found it
|
||||
// too loud,
|
||||
// so we now play on the music stream.
|
||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
mediaPlayer = new MediaPlayer();
|
||||
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||
mediaPlayer.setOnCompletionListener(beepListener);
|
||||
|
||||
AssetFileDescriptor file = getResources().openRawResourceFd(
|
||||
R.raw.beep);
|
||||
try {
|
||||
mediaPlayer.setDataSource(file.getFileDescriptor(),
|
||||
file.getStartOffset(), file.getLength());
|
||||
file.close();
|
||||
mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
|
||||
mediaPlayer.prepare();
|
||||
} catch (IOException e) {
|
||||
mediaPlayer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long VIBRATE_DURATION = 200L;
|
||||
|
||||
private void playBeepSoundAndVibrate() {
|
||||
if (playBeep && mediaPlayer != null) {
|
||||
mediaPlayer.start();
|
||||
}
|
||||
if (vibrate) {
|
||||
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
|
||||
vibrator.vibrate(VIBRATE_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When the beep has finished playing, rewind to queue up another one.
|
||||
*/
|
||||
private final OnCompletionListener beepListener = new OnCompletionListener() {
|
||||
public void onCompletion(MediaPlayer mediaPlayer) {
|
||||
mediaPlayer.seekTo(0);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.camera;
|
||||
|
||||
import android.hardware.Camera;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
final class AutoFocusCallback implements Camera.AutoFocusCallback {
|
||||
|
||||
private static final String TAG = AutoFocusCallback.class.getSimpleName();
|
||||
|
||||
private static final long AUTOFOCUS_INTERVAL_MS = 1500L;
|
||||
|
||||
private Handler autoFocusHandler;
|
||||
private int autoFocusMessage;
|
||||
|
||||
void setHandler(Handler autoFocusHandler, int autoFocusMessage) {
|
||||
this.autoFocusHandler = autoFocusHandler;
|
||||
this.autoFocusMessage = autoFocusMessage;
|
||||
}
|
||||
|
||||
public void onAutoFocus(boolean success, Camera camera) {
|
||||
if (autoFocusHandler != null) {
|
||||
Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success);
|
||||
autoFocusHandler.sendMessageDelayed(message, AUTOFOCUS_INTERVAL_MS);
|
||||
autoFocusHandler = null;
|
||||
} else {
|
||||
Log.d(TAG, "Got auto-focus callback, but no handler for it");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,280 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.camera;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.hardware.Camera;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.WindowManager;
|
||||
|
||||
final class CameraConfigurationManager {
|
||||
|
||||
private static final String TAG = CameraConfigurationManager.class.getSimpleName();
|
||||
|
||||
private static final int TEN_DESIRED_ZOOM = 27;
|
||||
private static final int DESIRED_SHARPNESS = 30;
|
||||
|
||||
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
||||
|
||||
private final Context context;
|
||||
private Point screenResolution;
|
||||
private Point cameraResolution;
|
||||
private int previewFormat;
|
||||
private String previewFormatString;
|
||||
|
||||
CameraConfigurationManager(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads, one time, values from the camera that are needed by the app.
|
||||
*/
|
||||
void initFromCameraParameters(Camera camera) {
|
||||
Camera.Parameters parameters = camera.getParameters();
|
||||
previewFormat = parameters.getPreviewFormat();
|
||||
previewFormatString = parameters.get("preview-format");
|
||||
Log.d(TAG, "Default preview format: " + previewFormat + '/' + previewFormatString);
|
||||
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
Display display = manager.getDefaultDisplay();
|
||||
screenResolution = new Point(display.getWidth(), display.getHeight());
|
||||
Log.d(TAG, "Screen resolution: " + screenResolution);
|
||||
|
||||
// //Lemon add 扫描框修改,解决拉伸但导致成像模糊识别率很低。<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
// Point screenResolutionForCamera = new Point();
|
||||
// screenResolutionForCamera.x = screenResolution.x;
|
||||
// screenResolutionForCamera.y = screenResolution.y;
|
||||
// // preview size is always something like 480*320, other 320*480
|
||||
// if (screenResolution.x < screenResolution.y) {
|
||||
// screenResolutionForCamera.x = screenResolution.y;
|
||||
// screenResolutionForCamera.y = screenResolution.x;
|
||||
// }
|
||||
//Lemon add 扫描框修改,解决拉伸>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//Lemon 扫描框修改,解决拉伸但导致成像模糊识别率很低 screenResolution改为screenResolutionForCamera);<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
cameraResolution = getCameraResolution(parameters, screenResolution);
|
||||
Log.d(TAG, "Camera resolution: " + screenResolution);
|
||||
//Lemon 扫描框修改,解决拉伸但导致成像模糊识别率很低 screenResolution改为screenResolutionForCamera);>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera up to take preview images which are used for both preview and decoding.
|
||||
* We detect the preview format here so that buildLuminanceSource() can build an appropriate
|
||||
* LuminanceSource subclass. In the future we may want to force YUV420SP as it's the smallest,
|
||||
* and the planar Y can be used for barcode scanning without a copy in some cases.
|
||||
*/
|
||||
void setDesiredCameraParameters(Camera camera) {
|
||||
Camera.Parameters parameters = camera.getParameters();
|
||||
Log.d(TAG, "Setting preview size: " + cameraResolution);
|
||||
parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
|
||||
setFlash(parameters);
|
||||
setZoom(parameters);
|
||||
//setSharpness(parameters);
|
||||
//modify here
|
||||
camera.setDisplayOrientation(90);
|
||||
camera.setParameters(parameters);
|
||||
}
|
||||
|
||||
Point getCameraResolution() {
|
||||
return cameraResolution;
|
||||
}
|
||||
|
||||
Point getScreenResolution() {
|
||||
return screenResolution;
|
||||
}
|
||||
|
||||
int getPreviewFormat() {
|
||||
return previewFormat;
|
||||
}
|
||||
|
||||
String getPreviewFormatString() {
|
||||
return previewFormatString;
|
||||
}
|
||||
|
||||
private static Point getCameraResolution(Camera.Parameters parameters, Point screenResolution) {
|
||||
|
||||
String previewSizeValueString = parameters.get("preview-size-values");
|
||||
// saw this on Xperia
|
||||
if (previewSizeValueString == null) {
|
||||
previewSizeValueString = parameters.get("preview-size-value");
|
||||
}
|
||||
|
||||
Point cameraResolution = null;
|
||||
|
||||
if (previewSizeValueString != null) {
|
||||
Log.d(TAG, "preview-size-values parameter: " + previewSizeValueString);
|
||||
cameraResolution = findBestPreviewSizeValue(previewSizeValueString, screenResolution);
|
||||
}
|
||||
|
||||
if (cameraResolution == null) {
|
||||
// Ensure that the camera resolution is a multiple of 8, as the screen may not be.
|
||||
cameraResolution = new Point(
|
||||
(screenResolution.x >> 3) << 3,
|
||||
(screenResolution.y >> 3) << 3);
|
||||
}
|
||||
|
||||
return cameraResolution;
|
||||
}
|
||||
|
||||
private static Point findBestPreviewSizeValue(CharSequence previewSizeValueString, Point screenResolution) {
|
||||
int bestX = 0;
|
||||
int bestY = 0;
|
||||
int diff = Integer.MAX_VALUE;
|
||||
for (String previewSize : COMMA_PATTERN.split(previewSizeValueString)) {
|
||||
|
||||
previewSize = previewSize.trim();
|
||||
int dimPosition = previewSize.indexOf('x');
|
||||
if (dimPosition < 0) {
|
||||
Log.w(TAG, "Bad preview-size: " + previewSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
int newX;
|
||||
int newY;
|
||||
try {
|
||||
newX = Integer.parseInt(previewSize.substring(0, dimPosition));
|
||||
newY = Integer.parseInt(previewSize.substring(dimPosition + 1));
|
||||
} catch (NumberFormatException nfe) {
|
||||
Log.w(TAG, "Bad preview-size: " + previewSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y);
|
||||
if (newDiff == 0) {
|
||||
bestX = newX;
|
||||
bestY = newY;
|
||||
break;
|
||||
} else if (newDiff < diff) {
|
||||
bestX = newX;
|
||||
bestY = newY;
|
||||
diff = newDiff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (bestX > 0 && bestY > 0) {
|
||||
return new Point(bestX, bestY);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int findBestMotZoomValue(CharSequence stringValues, int tenDesiredZoom) {
|
||||
int tenBestValue = 0;
|
||||
for (String stringValue : COMMA_PATTERN.split(stringValues)) {
|
||||
stringValue = stringValue.trim();
|
||||
double value;
|
||||
try {
|
||||
value = Double.parseDouble(stringValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return tenDesiredZoom;
|
||||
}
|
||||
int tenValue = (int) (10.0 * value);
|
||||
if (Math.abs(tenDesiredZoom - value) < Math.abs(tenDesiredZoom - tenBestValue)) {
|
||||
tenBestValue = tenValue;
|
||||
}
|
||||
}
|
||||
return tenBestValue;
|
||||
}
|
||||
|
||||
private void setFlash(Camera.Parameters parameters) {
|
||||
// FIXME: This is a hack to turn the flash off on the Samsung Galaxy.
|
||||
// And this is a hack-hack to work around a different value on the Behold II
|
||||
// Restrict Behold II check to Cupcake, per Samsung's advice
|
||||
//if (Build.MODEL.contains("Behold II") &&
|
||||
// CameraManager.SDK_INT == Build.VERSION_CODES.CUPCAKE) {
|
||||
if (Build.MODEL.contains("Behold II") && CameraManager.SDK_INT == 3) { // 3 = Cupcake
|
||||
parameters.set("flash-value", 1);
|
||||
} else {
|
||||
parameters.set("flash-value", 2);
|
||||
}
|
||||
// This is the standard setting to turn the flash off that all devices should honor.
|
||||
parameters.set("flash-mode", "off");
|
||||
}
|
||||
|
||||
private void setZoom(Camera.Parameters parameters) {
|
||||
|
||||
String zoomSupportedString = parameters.get("zoom-supported");
|
||||
if (zoomSupportedString != null && !Boolean.parseBoolean(zoomSupportedString)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int tenDesiredZoom = TEN_DESIRED_ZOOM;
|
||||
|
||||
String maxZoomString = parameters.get("max-zoom");
|
||||
if (maxZoomString != null) {
|
||||
try {
|
||||
int tenMaxZoom = (int) (10.0 * Double.parseDouble(maxZoomString));
|
||||
if (tenDesiredZoom > tenMaxZoom) {
|
||||
tenDesiredZoom = tenMaxZoom;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
Log.w(TAG, "Bad max-zoom: " + maxZoomString);
|
||||
}
|
||||
}
|
||||
|
||||
String takingPictureZoomMaxString = parameters.get("taking-picture-zoom-max");
|
||||
if (takingPictureZoomMaxString != null) {
|
||||
try {
|
||||
int tenMaxZoom = Integer.parseInt(takingPictureZoomMaxString);
|
||||
if (tenDesiredZoom > tenMaxZoom) {
|
||||
tenDesiredZoom = tenMaxZoom;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
Log.w(TAG, "Bad taking-picture-zoom-max: " + takingPictureZoomMaxString);
|
||||
}
|
||||
}
|
||||
|
||||
String motZoomValuesString = parameters.get("mot-zoom-values");
|
||||
if (motZoomValuesString != null) {
|
||||
tenDesiredZoom = findBestMotZoomValue(motZoomValuesString, tenDesiredZoom);
|
||||
}
|
||||
|
||||
String motZoomStepString = parameters.get("mot-zoom-step");
|
||||
if (motZoomStepString != null) {
|
||||
try {
|
||||
double motZoomStep = Double.parseDouble(motZoomStepString.trim());
|
||||
int tenZoomStep = (int) (10.0 * motZoomStep);
|
||||
if (tenZoomStep > 1) {
|
||||
tenDesiredZoom -= tenDesiredZoom % tenZoomStep;
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
// continue
|
||||
}
|
||||
}
|
||||
|
||||
// Set zoom. This helps encourage the user to pull back.
|
||||
// Some devices like the Behold have a zoom parameter
|
||||
if (maxZoomString != null || motZoomValuesString != null) {
|
||||
parameters.set("zoom", String.valueOf(tenDesiredZoom / 10.0));
|
||||
}
|
||||
|
||||
// Most devices, like the Hero, appear to expose this zoom parameter.
|
||||
// It takes on values like "27" which appears to mean 2.7x zoom
|
||||
if (takingPictureZoomMaxString != null) {
|
||||
parameters.set("taking-picture-zoom", tenDesiredZoom);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getDesiredSharpness() {
|
||||
return DESIRED_SHARPNESS;
|
||||
}
|
||||
|
||||
}
|
@ -1,364 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.camera;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.Parameters;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceHolder;
|
||||
|
||||
/**
|
||||
* This object wraps the Camera service object and expects to be the only one talking to it. The
|
||||
* implementation encapsulates the steps needed to take preview-sized images, which are used for
|
||||
* both preview and decoding.
|
||||
*
|
||||
*/
|
||||
public final class CameraManager {
|
||||
|
||||
private static final String TAG = CameraManager.class.getSimpleName();
|
||||
|
||||
private static final int MIN_FRAME_WIDTH = 240;
|
||||
private static final int MIN_FRAME_HEIGHT = 240;
|
||||
private static final int MAX_FRAME_WIDTH = 480;
|
||||
private static final int MAX_FRAME_HEIGHT = 360;
|
||||
|
||||
private static CameraManager cameraManager;
|
||||
|
||||
static final int SDK_INT; // Later we can use Build.VERSION.SDK_INT
|
||||
static {
|
||||
int sdkInt;
|
||||
try {
|
||||
sdkInt = Integer.parseInt(Build.VERSION.SDK);
|
||||
} catch (NumberFormatException nfe) {
|
||||
// Just to be safe
|
||||
sdkInt = 10000;
|
||||
}
|
||||
SDK_INT = sdkInt;
|
||||
}
|
||||
|
||||
private final Context context;
|
||||
private final CameraConfigurationManager configManager;
|
||||
private Camera camera;
|
||||
private Rect framingRect;
|
||||
private Rect framingRectInPreview;
|
||||
private boolean initialized;
|
||||
private boolean previewing;
|
||||
private final boolean useOneShotPreviewCallback;
|
||||
/**
|
||||
* Preview frames are delivered here, which we pass on to the registered handler. Make sure to
|
||||
* clear the handler so it will only receive one message.
|
||||
*/
|
||||
private final PreviewCallback previewCallback;
|
||||
/** Autofocus callbacks arrive here, and are dispatched to the Handler which requested them. */
|
||||
private final AutoFocusCallback autoFocusCallback;
|
||||
|
||||
/**
|
||||
* Initializes this static object with the Context of the calling Activity.
|
||||
*
|
||||
* @param context The Activity which wants to use the camera.
|
||||
*/
|
||||
public static void init(Context context) {
|
||||
if (cameraManager == null) {
|
||||
cameraManager = new CameraManager(context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CameraManager singleton instance.
|
||||
*
|
||||
* @return A reference to the CameraManager singleton.
|
||||
*/
|
||||
public static CameraManager get() {
|
||||
return cameraManager;
|
||||
}
|
||||
|
||||
private CameraManager(Context context) {
|
||||
|
||||
this.context = context;
|
||||
this.configManager = new CameraConfigurationManager(context);
|
||||
|
||||
// Camera.setOneShotPreviewCallback() has a race condition in Cupcake, so we use the older
|
||||
// Camera.setPreviewCallback() on 1.5 and earlier. For Donut and later, we need to use
|
||||
// the more efficient one shot callback, as the older one can swamp the system and cause it
|
||||
// to run out of memory. We can't use SDK_INT because it was introduced in the Donut SDK.
|
||||
//useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > Build.VERSION_CODES.CUPCAKE;
|
||||
useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > 3; // 3 = Cupcake
|
||||
|
||||
previewCallback = new PreviewCallback(configManager, useOneShotPreviewCallback);
|
||||
autoFocusCallback = new AutoFocusCallback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the camera driver and initializes the hardware parameters.
|
||||
*
|
||||
* @param holder The surface object which the camera will draw preview frames into.
|
||||
* @throws IOException Indicates the camera driver failed to open.
|
||||
*/
|
||||
public void openDriver(SurfaceHolder holder) throws IOException {
|
||||
if (camera == null) {
|
||||
camera = Camera.open();
|
||||
if (camera == null) {
|
||||
throw new IOException();
|
||||
}
|
||||
camera.setPreviewDisplay(holder);
|
||||
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
configManager.initFromCameraParameters(camera);
|
||||
}
|
||||
configManager.setDesiredCameraParameters(camera);
|
||||
|
||||
//FIXME
|
||||
// SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
//<EFBFBD>Ƿ<EFBFBD>ʹ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD>
|
||||
// if (prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false)) {
|
||||
// FlashlightManager.enableFlashlight();
|
||||
// }
|
||||
FlashlightManager.enableFlashlight();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Lemon add <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
private Parameters parameter;
|
||||
/**开关闪光灯
|
||||
* @param open
|
||||
* @return
|
||||
*/
|
||||
public boolean switchLight(boolean open) {
|
||||
parameter = camera.getParameters();
|
||||
if (open) {
|
||||
parameter.setFlashMode(Parameters.FLASH_MODE_TORCH);
|
||||
camera.setParameters(parameter);
|
||||
return true;
|
||||
} else {
|
||||
parameter.setFlashMode(Parameters.FLASH_MODE_OFF);
|
||||
camera.setParameters(parameter);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//Lemon add >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
/**
|
||||
* Closes the camera driver if still in use.
|
||||
*/
|
||||
public void closeDriver() {
|
||||
if (camera != null) {
|
||||
FlashlightManager.disableFlashlight();
|
||||
camera.release();
|
||||
camera = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the camera hardware to begin drawing preview frames to the screen.
|
||||
*/
|
||||
public void startPreview() {
|
||||
if (camera != null && !previewing) {
|
||||
camera.startPreview();
|
||||
previewing = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the camera to stop drawing preview frames.
|
||||
*/
|
||||
public void stopPreview() {
|
||||
if (camera != null && previewing) {
|
||||
if (!useOneShotPreviewCallback) {
|
||||
camera.setPreviewCallback(null);
|
||||
}
|
||||
camera.stopPreview();
|
||||
previewCallback.setHandler(null, 0);
|
||||
autoFocusCallback.setHandler(null, 0);
|
||||
previewing = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A single preview frame will be returned to the handler supplied. The data will arrive as byte[]
|
||||
* in the message.obj field, with width and height encoded as message.arg1 and message.arg2,
|
||||
* respectively.
|
||||
*
|
||||
* @param handler The handler to send the message to.
|
||||
* @param message The what field of the message to be sent.
|
||||
*/
|
||||
public void requestPreviewFrame(Handler handler, int message) {
|
||||
if (camera != null && previewing) {
|
||||
previewCallback.setHandler(handler, message);
|
||||
if (useOneShotPreviewCallback) {
|
||||
camera.setOneShotPreviewCallback(previewCallback);
|
||||
} else {
|
||||
camera.setPreviewCallback(previewCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the camera hardware to perform an autofocus.
|
||||
*
|
||||
* @param handler The Handler to notify when the autofocus completes.
|
||||
* @param message The message to deliver.
|
||||
*/
|
||||
public void requestAutoFocus(Handler handler, int message) {
|
||||
if (camera != null && previewing) {
|
||||
autoFocusCallback.setHandler(handler, message);
|
||||
//Log.d(TAG, "Requesting auto-focus callback");
|
||||
camera.autoFocus(autoFocusCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the framing rect which the UI should draw to show the user where to place the
|
||||
* barcode. This target helps with alignment as well as forces the user to hold the device
|
||||
* far enough away to ensure the image will be in focus.
|
||||
*
|
||||
* @return The rectangle to draw on screen in window coordinates.
|
||||
*/
|
||||
public Rect getFramingRect() {
|
||||
Point screenResolution = configManager.getScreenResolution();
|
||||
if (framingRect == null) {
|
||||
if (camera == null) {
|
||||
return null;
|
||||
}
|
||||
//Lemon 扫描框修改,解决拉伸<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
// int width = screenResolution.x * 3 / 4;
|
||||
// if (width < MIN_FRAME_WIDTH) {
|
||||
// width = MIN_FRAME_WIDTH;
|
||||
// } else if (width > MAX_FRAME_WIDTH) {
|
||||
// width = MAX_FRAME_WIDTH;
|
||||
// }
|
||||
// int height = screenResolution.y * 3 / 4;
|
||||
// if (height < MIN_FRAME_HEIGHT) {
|
||||
// height = MIN_FRAME_HEIGHT;
|
||||
// } else if (height > MAX_FRAME_HEIGHT) {
|
||||
// height = MAX_FRAME_HEIGHT;
|
||||
// }
|
||||
// int leftOffset = (screenResolution.x - width) / 2;
|
||||
// int topOffset = (screenResolution.y - height) / 2;
|
||||
// framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
|
||||
// Log.d(TAG, "Calculated framing rect: " + framingRect);
|
||||
|
||||
//Lemon 扫描框修改,解决拉伸<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
|
||||
int width = (int) (metrics.widthPixels * 0.6);
|
||||
int height = (int) (width * 0.9);
|
||||
|
||||
int leftOffset = (screenResolution.x - width) / 2;
|
||||
int topOffset = (screenResolution.y - height) / 3;
|
||||
framingRect = new Rect(leftOffset, topOffset, leftOffset + width,
|
||||
topOffset + height);
|
||||
Log.d(TAG, "Calculated framing rect: " + framingRect);
|
||||
//Lemon 扫描框修改,解决拉伸>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
||||
return framingRect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #getFramingRect} but coordinates are in terms of the preview frame,
|
||||
* not UI / screen.
|
||||
*/
|
||||
public Rect getFramingRectInPreview() {
|
||||
if (framingRectInPreview == null) {
|
||||
Rect rect = new Rect(getFramingRect());
|
||||
Point cameraResolution = configManager.getCameraResolution();
|
||||
Point screenResolution = configManager.getScreenResolution();
|
||||
//modify here
|
||||
// rect.left = rect.left * cameraResolution.x / screenResolution.x;
|
||||
// rect.right = rect.right * cameraResolution.x / screenResolution.x;
|
||||
// rect.top = rect.top * cameraResolution.y / screenResolution.y;
|
||||
// rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;
|
||||
rect.left = rect.left * cameraResolution.y / screenResolution.x;
|
||||
rect.right = rect.right * cameraResolution.y / screenResolution.x;
|
||||
rect.top = rect.top * cameraResolution.x / screenResolution.y;
|
||||
rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
|
||||
framingRectInPreview = rect;
|
||||
}
|
||||
return framingRectInPreview;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the result points from still resolution coordinates to screen coordinates.
|
||||
*
|
||||
* @param points The points returned by the Reader subclass through Result.getResultPoints().
|
||||
* @return An array of Points scaled to the size of the framing rect and offset appropriately
|
||||
* so they can be drawn in screen coordinates.
|
||||
*/
|
||||
/*
|
||||
public Point[] convertResultPoints(ResultPoint[] points) {
|
||||
Rect frame = getFramingRectInPreview();
|
||||
int count = points.length;
|
||||
Point[] output = new Point[count];
|
||||
for (int x = 0; x < count; x++) {
|
||||
output[x] = new Point();
|
||||
output[x].x = frame.left + (int) (points[x].getX() + 0.5f);
|
||||
output[x].y = frame.top + (int) (points[x].getY() + 0.5f);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* A factory method to build the appropriate LuminanceSource object based on the format
|
||||
* of the preview buffers, as described by Camera.Parameters.
|
||||
*
|
||||
* @param data A preview frame.
|
||||
* @param width The width of the image.
|
||||
* @param height The height of the image.
|
||||
* @return A PlanarYUVLuminanceSource instance.
|
||||
*/
|
||||
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
|
||||
Rect rect = getFramingRectInPreview();
|
||||
int previewFormat = configManager.getPreviewFormat();
|
||||
String previewFormatString = configManager.getPreviewFormatString();
|
||||
switch (previewFormat) {
|
||||
// This is the standard Android format which all devices are REQUIRED to support.
|
||||
// In theory, it's the only one we should ever care about.
|
||||
case PixelFormat.YCbCr_420_SP:
|
||||
// This format has never been seen in the wild, but is compatible as we only care
|
||||
// about the Y channel, so allow it.
|
||||
case PixelFormat.YCbCr_422_SP:
|
||||
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
|
||||
rect.width(), rect.height());
|
||||
default:
|
||||
// The Samsung Work incorrectly uses this variant instead of the 'sp' version.
|
||||
// Fortunately, it too has all the Y data up front, so we can read it.
|
||||
if ("yuv420p".equals(previewFormatString)) {
|
||||
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
|
||||
rect.width(), rect.height());
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported picture format: " +
|
||||
previewFormat + '/' + previewFormatString);
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.camera;
|
||||
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* This class is used to activate the weak light on some camera phones (not flash)
|
||||
* in order to illuminate surfaces for scanning. There is no official way to do this,
|
||||
* but, classes which allow access to this function still exist on some devices.
|
||||
* This therefore proceeds through a great deal of reflection.
|
||||
*
|
||||
* See <a href="http://almondmendoza.com/2009/01/05/changing-the-screen-brightness-programatically/">
|
||||
* http://almondmendoza.com/2009/01/05/changing-the-screen-brightness-programatically/</a> and
|
||||
* <a href="http://code.google.com/p/droidled/source/browse/trunk/src/com/droidled/demo/DroidLED.java">
|
||||
* http://code.google.com/p/droidled/source/browse/trunk/src/com/droidled/demo/DroidLED.java</a>.
|
||||
* Thanks to Ryan Alford for pointing out the availability of this class.
|
||||
*/
|
||||
final class FlashlightManager {
|
||||
|
||||
private static final String TAG = FlashlightManager.class.getSimpleName();
|
||||
|
||||
private static final Object iHardwareService;
|
||||
private static final Method setFlashEnabledMethod;
|
||||
static {
|
||||
iHardwareService = getHardwareService();
|
||||
setFlashEnabledMethod = getSetFlashEnabledMethod(iHardwareService);
|
||||
if (iHardwareService == null) {
|
||||
Log.v(TAG, "This device does supports control of a flashlight");
|
||||
} else {
|
||||
Log.v(TAG, "This device does not support control of a flashlight");
|
||||
}
|
||||
}
|
||||
|
||||
private FlashlightManager() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启闪光灯
|
||||
*/
|
||||
//FIXME
|
||||
static void enableFlashlight() {
|
||||
setFlashlight(false);
|
||||
}
|
||||
|
||||
static void disableFlashlight() {
|
||||
setFlashlight(false);
|
||||
}
|
||||
|
||||
private static Object getHardwareService() {
|
||||
Class<?> serviceManagerClass = maybeForName("android.os.ServiceManager");
|
||||
if (serviceManagerClass == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Method getServiceMethod = maybeGetMethod(serviceManagerClass, "getService", String.class);
|
||||
if (getServiceMethod == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object hardwareService = invoke(getServiceMethod, null, "hardware");
|
||||
if (hardwareService == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Class<?> iHardwareServiceStubClass = maybeForName("android.os.IHardwareService$Stub");
|
||||
if (iHardwareServiceStubClass == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Method asInterfaceMethod = maybeGetMethod(iHardwareServiceStubClass, "asInterface", IBinder.class);
|
||||
if (asInterfaceMethod == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return invoke(asInterfaceMethod, null, hardwareService);
|
||||
}
|
||||
|
||||
private static Method getSetFlashEnabledMethod(Object iHardwareService) {
|
||||
if (iHardwareService == null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> proxyClass = iHardwareService.getClass();
|
||||
return maybeGetMethod(proxyClass, "setFlashlightEnabled", boolean.class);
|
||||
}
|
||||
|
||||
private static Class<?> maybeForName(String name) {
|
||||
try {
|
||||
return Class.forName(name);
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
// OK
|
||||
return null;
|
||||
} catch (RuntimeException re) {
|
||||
Log.w(TAG, "Unexpected error while finding class " + name, re);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method maybeGetMethod(Class<?> clazz, String name, Class<?>... argClasses) {
|
||||
try {
|
||||
return clazz.getMethod(name, argClasses);
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
// OK
|
||||
return null;
|
||||
} catch (RuntimeException re) {
|
||||
Log.w(TAG, "Unexpected error while finding method " + name, re);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Object invoke(Method method, Object instance, Object... args) {
|
||||
try {
|
||||
return method.invoke(instance, args);
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.w(TAG, "Unexpected error while invoking " + method, e);
|
||||
return null;
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.w(TAG, "Unexpected error while invoking " + method, e.getCause());
|
||||
return null;
|
||||
} catch (RuntimeException re) {
|
||||
Log.w(TAG, "Unexpected error while invoking " + method, re);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void setFlashlight(boolean active) {
|
||||
if (iHardwareService != null) {
|
||||
invoke(setFlashEnabledMethod, iHardwareService, active);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.camera;
|
||||
|
||||
import com.google.zxing.LuminanceSource;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
/**
|
||||
* This object extends LuminanceSource around an array of YUV data returned from the camera driver,
|
||||
* with the option to crop to a rectangle within the full data. This can be used to exclude
|
||||
* superfluous pixels around the perimeter and speed up decoding.
|
||||
*
|
||||
* It works for any pixel format where the Y channel is planar and appears first, including
|
||||
* YCbCr_420_SP and YCbCr_422_SP.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public final class PlanarYUVLuminanceSource extends LuminanceSource {
|
||||
private final byte[] yuvData;
|
||||
private final int dataWidth;
|
||||
private final int dataHeight;
|
||||
private final int left;
|
||||
private final int top;
|
||||
|
||||
public PlanarYUVLuminanceSource(byte[] yuvData, int dataWidth, int dataHeight, int left, int top,
|
||||
int width, int height) {
|
||||
super(width, height);
|
||||
|
||||
if (left + width > dataWidth || top + height > dataHeight) {
|
||||
throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
|
||||
}
|
||||
|
||||
this.yuvData = yuvData;
|
||||
this.dataWidth = dataWidth;
|
||||
this.dataHeight = dataHeight;
|
||||
this.left = left;
|
||||
this.top = top;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getRow(int y, byte[] row) {
|
||||
if (y < 0 || y >= getHeight()) {
|
||||
throw new IllegalArgumentException("Requested row is outside the image: " + y);
|
||||
}
|
||||
int width = getWidth();
|
||||
if (row == null || row.length < width) {
|
||||
row = new byte[width];
|
||||
}
|
||||
int offset = (y + top) * dataWidth + left;
|
||||
System.arraycopy(yuvData, offset, row, 0, width);
|
||||
return row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getMatrix() {
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
|
||||
// If the caller asks for the entire underlying image, save the copy and give them the
|
||||
// original data. The docs specifically warn that result.length must be ignored.
|
||||
if (width == dataWidth && height == dataHeight) {
|
||||
return yuvData;
|
||||
}
|
||||
|
||||
int area = width * height;
|
||||
byte[] matrix = new byte[area];
|
||||
int inputOffset = top * dataWidth + left;
|
||||
|
||||
// If the width matches the full width of the underlying data, perform a single copy.
|
||||
if (width == dataWidth) {
|
||||
System.arraycopy(yuvData, inputOffset, matrix, 0, area);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
// Otherwise copy one cropped row at a time.
|
||||
byte[] yuv = yuvData;
|
||||
for (int y = 0; y < height; y++) {
|
||||
int outputOffset = y * width;
|
||||
System.arraycopy(yuv, inputOffset, matrix, outputOffset, width);
|
||||
inputOffset += dataWidth;
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCropSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getDataWidth() {
|
||||
return dataWidth;
|
||||
}
|
||||
|
||||
public int getDataHeight() {
|
||||
return dataHeight;
|
||||
}
|
||||
|
||||
public Bitmap renderCroppedGreyscaleBitmap() {
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int[] pixels = new int[width * height];
|
||||
byte[] yuv = yuvData;
|
||||
int inputOffset = top * dataWidth + left;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
int outputOffset = y * width;
|
||||
for (int x = 0; x < width; x++) {
|
||||
int grey = yuv[inputOffset + x] & 0xff;
|
||||
pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101);
|
||||
}
|
||||
inputOffset += dataWidth;
|
||||
}
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
|
||||
return bitmap;
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.camera;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.hardware.Camera;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
final class PreviewCallback implements Camera.PreviewCallback {
|
||||
|
||||
private static final String TAG = PreviewCallback.class.getSimpleName();
|
||||
|
||||
private final CameraConfigurationManager configManager;
|
||||
private final boolean useOneShotPreviewCallback;
|
||||
private Handler previewHandler;
|
||||
private int previewMessage;
|
||||
|
||||
PreviewCallback(CameraConfigurationManager configManager, boolean useOneShotPreviewCallback) {
|
||||
this.configManager = configManager;
|
||||
this.useOneShotPreviewCallback = useOneShotPreviewCallback;
|
||||
}
|
||||
|
||||
void setHandler(Handler previewHandler, int previewMessage) {
|
||||
this.previewHandler = previewHandler;
|
||||
this.previewMessage = previewMessage;
|
||||
}
|
||||
|
||||
public void onPreviewFrame(byte[] data, Camera camera) {
|
||||
Point cameraResolution = configManager.getCameraResolution();
|
||||
if (!useOneShotPreviewCallback) {
|
||||
camera.setPreviewCallback(null);
|
||||
}
|
||||
if (previewHandler != null) {
|
||||
Message message = previewHandler.obtainMessage(previewMessage, cameraResolution.x,
|
||||
cameraResolution.y, data);
|
||||
message.sendToTarget();
|
||||
previewHandler = null;
|
||||
} else {
|
||||
Log.d(TAG, "Got preview callback, but no handler for it");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.decoding;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import com.ericssonlabs.R;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.Result;
|
||||
import com.zxing.activity.CaptureActivity;
|
||||
import com.zxing.camera.CameraManager;
|
||||
import com.zxing.view.ViewfinderResultPointCallback;
|
||||
import com.zxing.view.ViewfinderView;
|
||||
|
||||
/**
|
||||
* This class handles all the messaging which comprises the state machine for capture.
|
||||
*/
|
||||
public final class CaptureActivityHandler extends Handler {
|
||||
private static final String TAG = CaptureActivityHandler.class.getSimpleName();
|
||||
|
||||
public interface DecodeCallback {
|
||||
void handleDecode(Result result, Bitmap barcode);
|
||||
void drawViewfinder();
|
||||
}
|
||||
|
||||
private State state;
|
||||
private enum State {
|
||||
PREVIEW,
|
||||
SUCCESS,
|
||||
DONE
|
||||
}
|
||||
|
||||
private final Activity activity;
|
||||
private final DecodeThread decodeThread;
|
||||
private DecodeCallback decodeCallback;
|
||||
public CaptureActivityHandler(CaptureActivity activity, Vector<BarcodeFormat> decodeFormats,
|
||||
String characterSet, ViewfinderView viewfinderView, DecodeCallback decodeCallback) {
|
||||
this.activity = activity;
|
||||
this.decodeCallback = decodeCallback;
|
||||
|
||||
decodeThread = new DecodeThread(activity, decodeFormats, characterSet,
|
||||
new ViewfinderResultPointCallback(viewfinderView));
|
||||
decodeThread.start();
|
||||
state = State.SUCCESS;
|
||||
// Start ourselves capturing previews and decoding.
|
||||
CameraManager.get().startPreview();
|
||||
restartPreviewAndDecode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
if (message.what == R.id.auto_focus) {
|
||||
//Log.d(TAG, "Got auto-focus message");
|
||||
// When one auto focus pass finishes, start another. This is the closest thing to
|
||||
// continuous AF. It does seem to hunt a bit, but I'm not sure what else to do.
|
||||
if (state == State.PREVIEW) {
|
||||
CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
|
||||
}
|
||||
}else if (message.what == R.id.restart_preview) {
|
||||
Log.d(TAG, "Got restart preview message");
|
||||
restartPreviewAndDecode();
|
||||
}else if (message.what == R.id.decode_succeeded) {
|
||||
Log.d(TAG, "Got decode succeeded message");
|
||||
state = State.SUCCESS;
|
||||
Bundle bundle = message.getData();
|
||||
|
||||
/***********************************************************************/
|
||||
Bitmap barcode = bundle == null ? null :
|
||||
(Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP);//<EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
||||
|
||||
decodeCallback.handleDecode((Result) message.obj, barcode);//<EFBFBD><EFBFBD><EFBFBD>ؽ<EFBFBD><EFBFBD>
|
||||
/***********************************************************************/
|
||||
}else if (message.what == R.id.decode_failed) {
|
||||
// We're decoding as fast as possible, so when one decode fails, start another.
|
||||
state = State.PREVIEW;
|
||||
CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
|
||||
}else if (message.what == R.id.return_scan_result) {
|
||||
Log.d(TAG, "Got return scan result message");
|
||||
activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
|
||||
activity.finish();
|
||||
}else if (message.what == R.id.launch_product_query) {
|
||||
Log.d(TAG, "Got product query message");
|
||||
String url = (String) message.obj;
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
public void quitSynchronously() {
|
||||
state = State.DONE;
|
||||
CameraManager.get().stopPreview();
|
||||
Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
|
||||
quit.sendToTarget();
|
||||
try {
|
||||
decodeThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
// continue
|
||||
}
|
||||
|
||||
// Be absolutely sure we don't send any queued up messages
|
||||
removeMessages(R.id.decode_succeeded);
|
||||
removeMessages(R.id.decode_failed);
|
||||
}
|
||||
|
||||
private void restartPreviewAndDecode() {
|
||||
if (state == State.SUCCESS) {
|
||||
state = State.PREVIEW;
|
||||
CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
|
||||
CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
|
||||
decodeCallback.drawViewfinder();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.decoding;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
final class DecodeFormatManager {
|
||||
|
||||
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
||||
|
||||
static final Vector<BarcodeFormat> PRODUCT_FORMATS;
|
||||
static final Vector<BarcodeFormat> ONE_D_FORMATS;
|
||||
static final Vector<BarcodeFormat> QR_CODE_FORMATS;
|
||||
static final Vector<BarcodeFormat> DATA_MATRIX_FORMATS;
|
||||
static {
|
||||
PRODUCT_FORMATS = new Vector<BarcodeFormat>(5);
|
||||
PRODUCT_FORMATS.add(BarcodeFormat.UPC_A);
|
||||
PRODUCT_FORMATS.add(BarcodeFormat.UPC_E);
|
||||
PRODUCT_FORMATS.add(BarcodeFormat.EAN_13);
|
||||
PRODUCT_FORMATS.add(BarcodeFormat.EAN_8);
|
||||
PRODUCT_FORMATS.add(BarcodeFormat.RSS14);
|
||||
ONE_D_FORMATS = new Vector<BarcodeFormat>(PRODUCT_FORMATS.size() + 4);
|
||||
ONE_D_FORMATS.addAll(PRODUCT_FORMATS);
|
||||
ONE_D_FORMATS.add(BarcodeFormat.CODE_39);
|
||||
ONE_D_FORMATS.add(BarcodeFormat.CODE_93);
|
||||
ONE_D_FORMATS.add(BarcodeFormat.CODE_128);
|
||||
ONE_D_FORMATS.add(BarcodeFormat.ITF);
|
||||
QR_CODE_FORMATS = new Vector<BarcodeFormat>(1);
|
||||
QR_CODE_FORMATS.add(BarcodeFormat.QR_CODE);
|
||||
DATA_MATRIX_FORMATS = new Vector<BarcodeFormat>(1);
|
||||
DATA_MATRIX_FORMATS.add(BarcodeFormat.DATA_MATRIX);
|
||||
}
|
||||
|
||||
private DecodeFormatManager() {}
|
||||
|
||||
static Vector<BarcodeFormat> parseDecodeFormats(Intent intent) {
|
||||
List<String> scanFormats = null;
|
||||
String scanFormatsString = intent.getStringExtra(Intents.Scan.SCAN_FORMATS);
|
||||
if (scanFormatsString != null) {
|
||||
scanFormats = Arrays.asList(COMMA_PATTERN.split(scanFormatsString));
|
||||
}
|
||||
return parseDecodeFormats(scanFormats, intent.getStringExtra(Intents.Scan.MODE));
|
||||
}
|
||||
|
||||
static Vector<BarcodeFormat> parseDecodeFormats(Uri inputUri) {
|
||||
List<String> formats = inputUri.getQueryParameters(Intents.Scan.SCAN_FORMATS);
|
||||
if (formats != null && formats.size() == 1 && formats.get(0) != null){
|
||||
formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0)));
|
||||
}
|
||||
return parseDecodeFormats(formats, inputUri.getQueryParameter(Intents.Scan.MODE));
|
||||
}
|
||||
|
||||
private static Vector<BarcodeFormat> parseDecodeFormats(Iterable<String> scanFormats,
|
||||
String decodeMode) {
|
||||
if (scanFormats != null) {
|
||||
Vector<BarcodeFormat> formats = new Vector<BarcodeFormat>();
|
||||
try {
|
||||
for (String format : scanFormats) {
|
||||
formats.add(BarcodeFormat.valueOf(format));
|
||||
}
|
||||
return formats;
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// ignore it then
|
||||
}
|
||||
}
|
||||
if (decodeMode != null) {
|
||||
if (Intents.Scan.PRODUCT_MODE.equals(decodeMode)) {
|
||||
return PRODUCT_FORMATS;
|
||||
}
|
||||
if (Intents.Scan.QR_CODE_MODE.equals(decodeMode)) {
|
||||
return QR_CODE_FORMATS;
|
||||
}
|
||||
if (Intents.Scan.DATA_MATRIX_MODE.equals(decodeMode)) {
|
||||
return DATA_MATRIX_FORMATS;
|
||||
}
|
||||
if (Intents.Scan.ONE_D_MODE.equals(decodeMode)) {
|
||||
return ONE_D_FORMATS;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.decoding;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import com.ericssonlabs.R;
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import com.google.zxing.DecodeHintType;
|
||||
import com.google.zxing.MultiFormatReader;
|
||||
import com.google.zxing.ReaderException;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import com.zxing.activity.CaptureActivity;
|
||||
import com.zxing.camera.CameraManager;
|
||||
import com.zxing.camera.PlanarYUVLuminanceSource;
|
||||
|
||||
final class DecodeHandler extends Handler {
|
||||
|
||||
private static final String TAG = DecodeHandler.class.getSimpleName();
|
||||
|
||||
private final CaptureActivity activity;
|
||||
private final MultiFormatReader multiFormatReader;
|
||||
|
||||
DecodeHandler(CaptureActivity activity, Hashtable<DecodeHintType, Object> hints) {
|
||||
multiFormatReader = new MultiFormatReader();
|
||||
multiFormatReader.setHints(hints);
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
if (message.what == R.id.decode) {
|
||||
//Log.d(TAG, "Got decode message");
|
||||
decode((byte[]) message.obj, message.arg1, message.arg2);
|
||||
}else if (message.what == R.id.quit) {
|
||||
Looper.myLooper().quit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,
|
||||
* reuse the same reader objects from one decode to the next.
|
||||
*
|
||||
* @param data The YUV preview frame.
|
||||
* @param width The width of the preview frame.
|
||||
* @param height The height of the preview frame.
|
||||
*/
|
||||
private void decode(byte[] data, int width, int height) {
|
||||
long start = System.currentTimeMillis();
|
||||
Result rawResult = null;
|
||||
|
||||
//modify here
|
||||
byte[] rotatedData = new byte[data.length];
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++)
|
||||
rotatedData[x * height + height - y - 1] = data[x + y * width];
|
||||
}
|
||||
int tmp = width; // Here we are swapping, that's the difference to #11
|
||||
width = height;
|
||||
height = tmp;
|
||||
|
||||
PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, width, height);
|
||||
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||
try {
|
||||
rawResult = multiFormatReader.decodeWithState(bitmap);
|
||||
} catch (ReaderException re) {
|
||||
// continue
|
||||
} finally {
|
||||
multiFormatReader.reset();
|
||||
}
|
||||
|
||||
if (rawResult != null) {
|
||||
long end = System.currentTimeMillis();
|
||||
Log.d(TAG, "Found barcode (" + (end - start) + " ms):\n" + rawResult.toString());
|
||||
Message message = Message.obtain(activity.getHandler(), R.id.decode_succeeded, rawResult);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap());
|
||||
message.setData(bundle);
|
||||
//Log.d(TAG, "Sending decode succeeded message...");
|
||||
message.sendToTarget();
|
||||
} else {
|
||||
Message message = Message.obtain(activity.getHandler(), R.id.decode_failed);
|
||||
message.sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.decoding;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.DecodeHintType;
|
||||
import com.google.zxing.ResultPointCallback;
|
||||
import com.zxing.activity.CaptureActivity;
|
||||
|
||||
/**
|
||||
* This thread does all the heavy lifting of decoding the images.
|
||||
* 编码线程
|
||||
*/
|
||||
final class DecodeThread extends Thread {
|
||||
|
||||
public static final String BARCODE_BITMAP = "barcode_bitmap";
|
||||
private final CaptureActivity activity;
|
||||
private final Hashtable<DecodeHintType, Object> hints;
|
||||
private Handler handler;
|
||||
private final CountDownLatch handlerInitLatch;
|
||||
|
||||
DecodeThread(CaptureActivity activity,
|
||||
Vector<BarcodeFormat> decodeFormats,
|
||||
String characterSet,
|
||||
ResultPointCallback resultPointCallback) {
|
||||
|
||||
this.activity = activity;
|
||||
handlerInitLatch = new CountDownLatch(1);
|
||||
|
||||
hints = new Hashtable<DecodeHintType, Object>(3);
|
||||
|
||||
if (decodeFormats == null || decodeFormats.isEmpty()) {
|
||||
decodeFormats = new Vector<BarcodeFormat>();
|
||||
decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
|
||||
decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
|
||||
decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
|
||||
}
|
||||
|
||||
hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
|
||||
|
||||
if (characterSet != null) {
|
||||
hints.put(DecodeHintType.CHARACTER_SET, characterSet);
|
||||
}
|
||||
|
||||
hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback);
|
||||
}
|
||||
|
||||
Handler getHandler() {
|
||||
try {
|
||||
handlerInitLatch.await();
|
||||
} catch (InterruptedException ie) {
|
||||
// continue?
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Looper.prepare();
|
||||
handler = new DecodeHandler(activity, hints);
|
||||
handlerInitLatch.countDown();
|
||||
Looper.loop();
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.decoding;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
|
||||
/**
|
||||
* Simple listener used to exit the app in a few cases.
|
||||
*
|
||||
*/
|
||||
public final class FinishListener
|
||||
implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener, Runnable {
|
||||
|
||||
private final Activity activityToFinish;
|
||||
|
||||
public FinishListener(Activity activityToFinish) {
|
||||
this.activityToFinish = activityToFinish;
|
||||
}
|
||||
|
||||
public void onCancel(DialogInterface dialogInterface) {
|
||||
run();
|
||||
}
|
||||
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
run();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
activityToFinish.finish();
|
||||
}
|
||||
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.decoding;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
/**
|
||||
* Finishes an activity after a period of inactivity.
|
||||
*/
|
||||
public final class InactivityTimer {
|
||||
|
||||
private static final int INACTIVITY_DELAY_SECONDS = 5 * 60;
|
||||
|
||||
private final ScheduledExecutorService inactivityTimer =
|
||||
Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory());
|
||||
private final Activity activity;
|
||||
private ScheduledFuture<?> inactivityFuture = null;
|
||||
|
||||
public InactivityTimer(Activity activity) {
|
||||
this.activity = activity;
|
||||
onActivity();
|
||||
}
|
||||
|
||||
public void onActivity() {
|
||||
cancel();
|
||||
inactivityFuture = inactivityTimer.schedule(new FinishListener(activity),
|
||||
INACTIVITY_DELAY_SECONDS,
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private void cancel() {
|
||||
if (inactivityFuture != null) {
|
||||
inactivityFuture.cancel(true);
|
||||
inactivityFuture = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
cancel();
|
||||
inactivityTimer.shutdown();
|
||||
}
|
||||
|
||||
private static final class DaemonThreadFactory implements ThreadFactory {
|
||||
public Thread newThread(Runnable runnable) {
|
||||
Thread thread = new Thread(runnable);
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,190 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.decoding;
|
||||
|
||||
/**
|
||||
* This class provides the constants to use when sending an Intent to Barcode Scanner.
|
||||
* These strings are effectively API and cannot be changed.
|
||||
*/
|
||||
public final class Intents {
|
||||
private Intents() {
|
||||
}
|
||||
|
||||
public static final class Scan {
|
||||
/**
|
||||
* Send this intent to open the Barcodes app in scanning mode, find a barcode, and return
|
||||
* the results.
|
||||
*/
|
||||
public static final String ACTION = "com.google.zxing.client.android.SCAN";
|
||||
|
||||
/**
|
||||
* By default, sending Scan.ACTION will decode all barcodes that we understand. However it
|
||||
* may be useful to limit scanning to certain formats. Use Intent.putExtra(MODE, value) with
|
||||
* one of the values below ({@link #PRODUCT_MODE}, {@link #ONE_D_MODE}, {@link #QR_CODE_MODE}).
|
||||
* Optional.
|
||||
*
|
||||
* Setting this is effectively shorthnad for setting explicit formats with {@link #SCAN_FORMATS}.
|
||||
* It is overridden by that setting.
|
||||
*/
|
||||
public static final String MODE = "SCAN_MODE";
|
||||
|
||||
/**
|
||||
* Comma-separated list of formats to scan for. The values must match the names of
|
||||
* {@link com.google.zxing.BarcodeFormat}s, such as {@link com.google.zxing.BarcodeFormat#EAN_13}.
|
||||
* Example: "EAN_13,EAN_8,QR_CODE"
|
||||
*
|
||||
* This overrides {@link #MODE}.
|
||||
*/
|
||||
public static final String SCAN_FORMATS = "SCAN_FORMATS";
|
||||
|
||||
/**
|
||||
* @see com.google.zxing.DecodeHintType#CHARACTER_SET
|
||||
*/
|
||||
public static final String CHARACTER_SET = "CHARACTER_SET";
|
||||
|
||||
/**
|
||||
* Decode only UPC and EAN barcodes. This is the right choice for shopping apps which get
|
||||
* prices, reviews, etc. for products.
|
||||
*/
|
||||
public static final String PRODUCT_MODE = "PRODUCT_MODE";
|
||||
|
||||
/**
|
||||
* Decode only 1D barcodes (currently UPC, EAN, Code 39, and Code 128).
|
||||
*/
|
||||
public static final String ONE_D_MODE = "ONE_D_MODE";
|
||||
|
||||
/**
|
||||
* Decode only QR codes.
|
||||
*/
|
||||
public static final String QR_CODE_MODE = "QR_CODE_MODE";
|
||||
|
||||
/**
|
||||
* Decode only Data Matrix codes.
|
||||
*/
|
||||
public static final String DATA_MATRIX_MODE = "DATA_MATRIX_MODE";
|
||||
|
||||
/**
|
||||
* If a barcode is found, Barcodes returns RESULT_OK to onActivityResult() of the app which
|
||||
* requested the scan via startSubActivity(). The barcodes contents can be retrieved with
|
||||
* intent.getStringExtra(RESULT). If the user presses Back, the result code will be
|
||||
* RESULT_CANCELED.
|
||||
*/
|
||||
public static final String RESULT = "SCAN_RESULT";
|
||||
|
||||
/**
|
||||
* Call intent.getStringExtra(RESULT_FORMAT) to determine which barcode format was found.
|
||||
* See Contents.Format for possible values.
|
||||
*/
|
||||
public static final String RESULT_FORMAT = "SCAN_RESULT_FORMAT";
|
||||
|
||||
/**
|
||||
* Setting this to false will not save scanned codes in the history.
|
||||
*/
|
||||
public static final String SAVE_HISTORY = "SAVE_HISTORY";
|
||||
|
||||
private Scan() {
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Encode {
|
||||
/**
|
||||
* Send this intent to encode a piece of data as a QR code and display it full screen, so
|
||||
* that another person can scan the barcode from your screen.
|
||||
*/
|
||||
public static final String ACTION = "com.google.zxing.client.android.ENCODE";
|
||||
|
||||
/**
|
||||
* The data to encode. Use Intent.putExtra(DATA, data) where data is either a String or a
|
||||
* Bundle, depending on the type and format specified. Non-QR Code formats should
|
||||
* just use a String here. For QR Code, see Contents for details.
|
||||
*/
|
||||
public static final String DATA = "ENCODE_DATA";
|
||||
|
||||
/**
|
||||
* The type of data being supplied if the format is QR Code. Use
|
||||
* Intent.putExtra(TYPE, type) with one of Contents.Type.
|
||||
*/
|
||||
public static final String TYPE = "ENCODE_TYPE";
|
||||
|
||||
/**
|
||||
* The barcode format to be displayed. If this isn't specified or is blank,
|
||||
* it defaults to QR Code. Use Intent.putExtra(FORMAT, format), where
|
||||
* format is one of Contents.Format.
|
||||
*/
|
||||
public static final String FORMAT = "ENCODE_FORMAT";
|
||||
|
||||
private Encode() {
|
||||
}
|
||||
}
|
||||
|
||||
public static final class SearchBookContents {
|
||||
/**
|
||||
* Use Google Book Search to search the contents of the book provided.
|
||||
*/
|
||||
public static final String ACTION = "com.google.zxing.client.android.SEARCH_BOOK_CONTENTS";
|
||||
|
||||
/**
|
||||
* The book to search, identified by ISBN number.
|
||||
*/
|
||||
public static final String ISBN = "ISBN";
|
||||
|
||||
/**
|
||||
* An optional field which is the text to search for.
|
||||
*/
|
||||
public static final String QUERY = "QUERY";
|
||||
|
||||
private SearchBookContents() {
|
||||
}
|
||||
}
|
||||
|
||||
public static final class WifiConnect {
|
||||
/**
|
||||
* Internal intent used to trigger connection to a wi-fi network.
|
||||
*/
|
||||
public static final String ACTION = "com.google.zxing.client.android.WIFI_CONNECT";
|
||||
|
||||
/**
|
||||
* The network to connect to, all the configuration provided here.
|
||||
*/
|
||||
public static final String SSID = "SSID";
|
||||
|
||||
/**
|
||||
* The network to connect to, all the configuration provided here.
|
||||
*/
|
||||
public static final String TYPE = "TYPE";
|
||||
|
||||
/**
|
||||
* The network to connect to, all the configuration provided here.
|
||||
*/
|
||||
public static final String PASSWORD = "PASSWORD";
|
||||
|
||||
private WifiConnect() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final class Share {
|
||||
/**
|
||||
* Give the user a choice of items to encode as a barcode, then render it as a QR Code and
|
||||
* display onscreen for a friend to scan with their phone.
|
||||
*/
|
||||
public static final String ACTION = "com.google.zxing.client.android.SHARE";
|
||||
|
||||
private Share() {
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.zxing.encoding;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.EncodeHintType;
|
||||
import com.google.zxing.MultiFormatWriter;
|
||||
import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
/**
|
||||
* @author Ryan Tang
|
||||
*
|
||||
*/
|
||||
public final class EncodingHandler {
|
||||
private static final int BLACK = 0xff000000;
|
||||
|
||||
public static Bitmap createQRCode(String str,int widthAndHeight) throws WriterException {
|
||||
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
|
||||
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
|
||||
BitMatrix matrix = new MultiFormatWriter().encode(str,
|
||||
BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
|
||||
int width = matrix.getWidth();
|
||||
int height = matrix.getHeight();
|
||||
int[] pixels = new int[width * height];
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
if (matrix.get(x, y)) {
|
||||
pixels[y * width + x] = BLACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
|
||||
return bitmap;
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.view;
|
||||
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.ResultPointCallback;
|
||||
|
||||
public final class ViewfinderResultPointCallback implements ResultPointCallback {
|
||||
|
||||
private final ViewfinderView viewfinderView;
|
||||
|
||||
public ViewfinderResultPointCallback(ViewfinderView viewfinderView) {
|
||||
this.viewfinderView = viewfinderView;
|
||||
}
|
||||
|
||||
public void foundPossibleResultPoint(ResultPoint point) {
|
||||
viewfinderView.addPossibleResultPoint(point);
|
||||
}
|
||||
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zxing.view;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.ericssonlabs.R;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.zxing.camera.CameraManager;
|
||||
|
||||
/**
|
||||
* This view is overlaid on top of the camera preview. It adds the viewfinder rectangle and partial
|
||||
* transparency outside it, as well as the laser scanner animation and result points.
|
||||
* 二维码扫描解析框
|
||||
*/
|
||||
public final class ViewfinderView extends View {
|
||||
|
||||
private static final int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64};
|
||||
private static final long ANIMATION_DELAY = 100L;
|
||||
private static final int OPAQUE = 0xFF;
|
||||
|
||||
private final Paint paint;
|
||||
private Bitmap resultBitmap;
|
||||
private final int maskColor;
|
||||
private final int resultColor;
|
||||
private final int frameColor;
|
||||
private final int laserColor;
|
||||
private final int resultPointColor;
|
||||
private int scannerAlpha;
|
||||
private Collection<ResultPoint> possibleResultPoints;
|
||||
private Collection<ResultPoint> lastPossibleResultPoints;
|
||||
|
||||
// This constructor is used when the class is built from an XML resource.
|
||||
public ViewfinderView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
// Initialize these once for performance rather than calling them every time in onDraw().
|
||||
paint = new Paint();
|
||||
Resources resources = getResources();
|
||||
maskColor = resources.getColor(R.color.viewfinder_mask);
|
||||
resultColor = resources.getColor(R.color.result_view);
|
||||
frameColor = resources.getColor(R.color.viewfinder_frame);
|
||||
laserColor = resources.getColor(R.color.viewfinder_laser);
|
||||
resultPointColor = resources.getColor(R.color.possible_result_points);
|
||||
scannerAlpha = 0;
|
||||
possibleResultPoints = new HashSet<ResultPoint>(5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
Rect frame = CameraManager.get().getFramingRect();
|
||||
if (frame == null) {
|
||||
return;
|
||||
}
|
||||
int width = canvas.getWidth();
|
||||
int height = canvas.getHeight();
|
||||
|
||||
// Draw the exterior (i.e. outside the framing rect) darkened
|
||||
paint.setColor(resultBitmap != null ? resultColor : maskColor);
|
||||
canvas.drawRect(0, 0, width, frame.top, paint);
|
||||
canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
|
||||
canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
|
||||
canvas.drawRect(0, frame.bottom + 1, width, height, paint);
|
||||
|
||||
if (resultBitmap != null) {
|
||||
// Draw the opaque result bitmap over the scanning rectangle
|
||||
paint.setAlpha(OPAQUE);
|
||||
canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint);
|
||||
} else {
|
||||
|
||||
// Draw a two pixel solid black border inside the framing rect
|
||||
paint.setColor(frameColor);
|
||||
canvas.drawRect(frame.left, frame.top, frame.right + 1, frame.top + 2, paint);
|
||||
canvas.drawRect(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1, paint);
|
||||
canvas.drawRect(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1, paint);
|
||||
canvas.drawRect(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1, paint);
|
||||
|
||||
// Draw a red "laser scanner" line through the middle to show decoding is active
|
||||
paint.setColor(laserColor);
|
||||
paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
|
||||
scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
|
||||
int middle = frame.height() / 2 + frame.top;
|
||||
canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
|
||||
|
||||
Collection<ResultPoint> currentPossible = possibleResultPoints;
|
||||
Collection<ResultPoint> currentLast = lastPossibleResultPoints;
|
||||
if (currentPossible.isEmpty()) {
|
||||
lastPossibleResultPoints = null;
|
||||
} else {
|
||||
possibleResultPoints = new HashSet<ResultPoint>(5);
|
||||
lastPossibleResultPoints = currentPossible;
|
||||
paint.setAlpha(OPAQUE);
|
||||
paint.setColor(resultPointColor);
|
||||
for (ResultPoint point : currentPossible) {
|
||||
canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 6.0f, paint);
|
||||
}
|
||||
}
|
||||
if (currentLast != null) {
|
||||
paint.setAlpha(OPAQUE / 2);
|
||||
paint.setColor(resultPointColor);
|
||||
for (ResultPoint point : currentLast) {
|
||||
canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 3.0f, paint);
|
||||
}
|
||||
}
|
||||
|
||||
// Request another update at the animation interval, but only repaint the laser line,
|
||||
// not the entire viewfinder mask.
|
||||
postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawViewfinder() {
|
||||
resultBitmap = null;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a bitmap with the result points highlighted instead of the live scanning display.
|
||||
*
|
||||
* @param barcode An image of the decoded barcode.
|
||||
*/
|
||||
public void drawResultBitmap(Bitmap barcode) {
|
||||
resultBitmap = barcode;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void addPossibleResultPoint(ResultPoint point) {
|
||||
possibleResultPoints.add(point);
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" >
|
||||
|
||||
<SurfaceView
|
||||
android:id="@+id/svCameraScan"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center" />
|
||||
|
||||
<com.zxing.view.ViewfinderView
|
||||
android:id="@+id/vfvCameraScan"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:background="#000000"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingTop="10dp"
|
||||
android:text="Scan Barcode"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_cancel_scan"
|
||||
android:layout_width="230dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginBottom="75dp"
|
||||
android:text="Cancel"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</FrameLayout>
|
@ -1,56 +0,0 @@
|
||||
<?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:background="@android:color/white"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_scan_barcode"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:text="Open camera" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@android:color/black"
|
||||
android:textSize="18sp"
|
||||
android:text="Scan result:" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_scan_result"
|
||||
android:layout_width="fill_parent"
|
||||
android:textSize="18sp"
|
||||
android:textColor="@android:color/black"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_qr_string"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:hint="Input the text"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_add_qrcode"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Generate QRcode" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_qr_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_gravity="center"/>
|
||||
|
||||
</LinearLayout>
|
Binary file not shown.
@ -1,2 +0,0 @@
|
||||
test: test
|
||||
admin: OBF:1u2a1toa1w8v1tok1u30,admin
|
@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
|
||||
<color name="bg_color">#EDEDED</color>
|
||||
<color name="contents_text">#ff000000</color>
|
||||
<color name="encode_view">#ffffffff</color>
|
||||
<color name="help_button_view">#ffcccccc</color>
|
||||
<color name="help_view">#ff404040</color>
|
||||
<color name="possible_result_points">#c0ffff00</color>
|
||||
<color name="result_image_border">#ffffffff</color>
|
||||
<color name="result_minor_text">#ffc0c0c0</color>
|
||||
<color name="result_points">#c000ff00</color>
|
||||
<color name="result_text">#ffffffff</color>
|
||||
<color name="result_view">#b0000000</color>
|
||||
<color name="sbc_header_text">#ff808080</color>
|
||||
<color name="sbc_header_view">#ffffffff</color>
|
||||
<color name="sbc_list_item">#fffff0e0</color>
|
||||
<color name="sbc_layout_view">#ffffffff</color>
|
||||
<color name="sbc_page_number_text">#ff000000</color>
|
||||
<color name="sbc_snippet_text">#ff4b4b4b</color>
|
||||
<color name="share_text">#ff000000</color>
|
||||
<color name="share_view">#ffffffff</color>
|
||||
<color name="status_view">#50000000</color>
|
||||
<color name="status_text">#ffffffff</color>
|
||||
<color name="transparent">#00000000</color>
|
||||
<color name="viewfinder_frame">#ff000000</color>
|
||||
<color name="viewfinder_laser">#ffff0000</color>
|
||||
<color name="viewfinder_mask">#60000000</color>
|
||||
<color name="header">#58567D</color>
|
||||
<color name="grgray">#686868</color>
|
||||
|
||||
</resources>
|
@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2008 ZXing authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Messages IDs -->
|
||||
<item type="id" name="auto_focus"/>
|
||||
<item type="id" name="decode"/>
|
||||
<item type="id" name="decode_failed"/>
|
||||
<item type="id" name="decode_succeeded"/>
|
||||
<item type="id" name="encode_failed"/>
|
||||
<item type="id" name="encode_succeeded"/>
|
||||
<item type="id" name="launch_product_query"/>
|
||||
<item type="id" name="quit"/>
|
||||
<item type="id" name="restart_preview"/>
|
||||
<item type="id" name="return_scan_result"/>
|
||||
<item type="id" name="search_book_contents_failed"/>
|
||||
<item type="id" name="search_book_contents_succeeded"/>
|
||||
</resources>
|
@ -1,15 +0,0 @@
|
||||
package com.ericssonlabs;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* To work on unit tests, switch the Test Artifact in the Build Variants view.
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() throws Exception {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
/build
|
@ -1,31 +0,0 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.0'
|
||||
defaultConfig {
|
||||
minSdkVersion 20
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
productFlavors {
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
testCompile 'junit:junit:4.12'
|
||||
compile files('libs/android-support-v4.jar')
|
||||
compile files('libs/okhttp-2.1.0.jar')
|
||||
compile files('libs/okio-1.0.0.jar')
|
||||
compile files('libs/universal-image-loader-1.9.4.jar')
|
||||
compile 'com.github.APIJSON:apijson-orm:3.9.0' // compile project(':APIJSONLibrary')
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,17 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /Users/Tommy/Library/Android/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
@ -1,13 +0,0 @@
|
||||
package zuo.biao.library;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="zuo.biao.library"
|
||||
android:versionCode="1"
|
||||
android:versionName="@string/app_version" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="15"
|
||||
android:targetSdkVersion="21" />
|
||||
|
||||
<!-- 复制粘贴到你的工程的AndroidManifest.xml内对应位置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -->
|
||||
|
||||
|
||||
<!-- 需要的权限 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<!-- CommonUtil等类的部分功能需要,不需要的功能对应的权限可不复制粘贴 <<<<<< -->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
<uses-permission android:name="android.permission.SEND_SMS" />
|
||||
<!-- CommonUtil等类的部分功能需要,不需要的功能对应的权限可不复制粘贴 >>>>>> -->
|
||||
<!-- 需要的权限 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
|
||||
<!-- 更好的适配全面屏 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>-->
|
||||
<meta-data android:name="android.max_aspect" android:value="2.1" />
|
||||
|
||||
<activity
|
||||
android:name="zuo.biao.library.ui.SelectPictureActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/WindowCompleteAlpha"
|
||||
android:windowSoftInputMode="stateAlwaysHidden" />
|
||||
<activity
|
||||
android:name="zuo.biao.library.ui.CutPictureActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Window"
|
||||
android:windowSoftInputMode="stateAlwaysHidden" />
|
||||
<activity
|
||||
android:name="zuo.biao.library.ui.WebViewActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="stateHidden|adjustResize|adjustUnspecified" />
|
||||
<activity
|
||||
android:name="zuo.biao.library.ui.EditTextInfoActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="stateVisible|adjustPan|adjustUnspecified" />
|
||||
<activity
|
||||
android:name="zuo.biao.library.ui.ServerSettingActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="stateHidden" />
|
||||
<activity
|
||||
android:name="zuo.biao.library.ui.TopMenuWindow"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Window"
|
||||
android:windowSoftInputMode="stateAlwaysHidden" />
|
||||
<activity
|
||||
android:name="zuo.biao.library.ui.BottomMenuWindow"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Window"
|
||||
android:windowSoftInputMode="stateAlwaysHidden" />
|
||||
<activity
|
||||
android:name="zuo.biao.library.ui.EditTextInfoWindow"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Window"
|
||||
android:windowSoftInputMode="stateVisible|adjustResize|adjustUnspecified" />
|
||||
<activity
|
||||
android:name="zuo.biao.library.ui.PlacePickerWindow"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Window"
|
||||
android:windowSoftInputMode="stateAlwaysHidden" />
|
||||
<activity
|
||||
android:name="zuo.biao.library.ui.DatePickerWindow"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Window"
|
||||
android:windowSoftInputMode="stateAlwaysHidden" />
|
||||
<activity
|
||||
android:name="zuo.biao.library.ui.TimePickerWindow"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Window"
|
||||
android:windowSoftInputMode="stateAlwaysHidden" />
|
||||
|
||||
</application>
|
||||
|
||||
<!-- 复制粘贴到你的工程的AndroidManifest.xml内对应位置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||
|
||||
</manifest>
|
@ -1,727 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.interfaces.ActivityPresenter;
|
||||
import zuo.biao.library.interfaces.OnBottomDragListener;
|
||||
import zuo.biao.library.manager.SystemBarTintManager;
|
||||
import zuo.biao.library.manager.ThreadManager;
|
||||
import zuo.biao.library.util.Log;
|
||||
import zuo.biao.library.util.ScreenUtil;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.GestureDetector.OnGestureListener;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**基础android.support.v4.app.FragmentActivity,通过继承可获取或使用 里面创建的 组件 和 方法
|
||||
* *onFling内控制左右滑动手势操作范围,可自定义
|
||||
* @author Lemon
|
||||
* @see ActivityPresenter#getActivity
|
||||
* @see #context
|
||||
* @see #view
|
||||
* @see #fragmentManager
|
||||
* @see #setContentView
|
||||
* @see #runUiThread
|
||||
* @see #runThread
|
||||
* @see #onDestroy
|
||||
* @use extends BaseActivity, 具体参考 .DemoActivity 和 .DemoFragmentActivity
|
||||
*/
|
||||
public abstract class BaseActivity extends FragmentActivity implements ActivityPresenter, OnGestureListener {
|
||||
private static final String TAG = "BaseActivity";
|
||||
|
||||
/**
|
||||
* 该Activity实例,命名为context是因为大部分方法都只需要context,写成context使用更方便
|
||||
* @warn 不能在子类中创建
|
||||
*/
|
||||
protected BaseActivity context = null;
|
||||
/**
|
||||
* 该Activity的界面,即contentView
|
||||
* @warn 不能在子类中创建
|
||||
*/
|
||||
protected View view = null;
|
||||
/**
|
||||
* 布局解释器
|
||||
* @warn 不能在子类中创建
|
||||
*/
|
||||
protected LayoutInflater inflater = null;
|
||||
/**
|
||||
* Fragment管理器
|
||||
* @warn 不能在子类中创建
|
||||
*/
|
||||
protected FragmentManager fragmentManager = null;
|
||||
|
||||
private boolean isAlive = false;
|
||||
private boolean isRunning = false;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
context = (BaseActivity) getActivity();
|
||||
isAlive = true;
|
||||
fragmentManager = getSupportFragmentManager();
|
||||
|
||||
inflater = getLayoutInflater();
|
||||
|
||||
threadNameList = new ArrayList<String>();
|
||||
|
||||
BaseBroadcastReceiver.register(context, receiver, ACTION_EXIT_APP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认标题旁边的进度环,layout.xml中用@id/pbBaseTitle绑定。
|
||||
* @warn 如果子Activity的layout中没有android:id="@id/pbBaseTitle"的pbBaseTitle,使用前必须在子Activity中赋值
|
||||
*/
|
||||
@Nullable
|
||||
protected ProgressBar pbBaseTitle;
|
||||
/**
|
||||
* 默认标题TextView,layout.xml中用@id/tvBaseTitle绑定。子Activity内调用autoSetTitle方法 会优先使用INTENT_TITLE
|
||||
* @see #autoSetTitle
|
||||
* @warn 如果子Activity的layout中没有android:id="@id/tvBaseTitle"的TextView,使用前必须在子Activity中赋值
|
||||
*/
|
||||
@Nullable
|
||||
protected TextView tvBaseTitle;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||
@Override
|
||||
public void setContentView(int layoutResID) {
|
||||
super.setContentView(layoutResID);
|
||||
|
||||
// 状态栏沉浸,4.4+生效 <<<<<<<<<<<<<<<<<
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
getWindow().setFlags(
|
||||
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
|
||||
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
}
|
||||
SystemBarTintManager tintManager = new SystemBarTintManager(this);
|
||||
tintManager.setStatusBarTintEnabled(true);
|
||||
tintManager.setStatusBarTintResource(R.color.topbar_bg);//状态背景色,可传drawable资源
|
||||
// 状态栏沉浸,4.4+生效 >>>>>>>>>>>>>>>>>
|
||||
|
||||
pbBaseTitle = (ProgressBar) findViewById(R.id.pbBaseTitle);//绑定默认标题旁ProgressBar
|
||||
tvBaseTitle = (TextView) findViewById(R.id.tvBaseTitle);//绑定默认标题TextView
|
||||
}
|
||||
|
||||
//底部滑动实现同点击标题栏左右按钮效果<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private OnBottomDragListener onBottomDragListener;
|
||||
private GestureDetector gestureDetector;
|
||||
/**设置该Activity界面布局,并设置底部左右滑动手势监听
|
||||
* @param layoutResID
|
||||
* @param listener
|
||||
* @use 在子类中
|
||||
* *1.onCreate中super.onCreate后setContentView(layoutResID, this);
|
||||
* *2.重写onDragBottom方法并实现滑动事件处理
|
||||
* *3.在导航栏左右按钮的onClick事件中调用onDragBottom方法
|
||||
*/
|
||||
public void setContentView(int layoutResID, OnBottomDragListener listener) {
|
||||
setContentView(layoutResID);
|
||||
|
||||
onBottomDragListener = listener;
|
||||
gestureDetector = new GestureDetector(this, this);//初始化手势监听类
|
||||
|
||||
view = inflater.inflate(layoutResID, null);
|
||||
view.setOnTouchListener(new OnTouchListener() {
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
return gestureDetector.onTouchEvent(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//底部滑动实现同点击标题栏左右按钮效果>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
/**
|
||||
* 用于 打开activity以及activity之间的通讯(传值)等;一些通讯相关基本操作(打电话、发短信等)
|
||||
*/
|
||||
protected Intent intent = null;
|
||||
|
||||
/**
|
||||
* 退出时之前的界面进入动画,可在finish();前通过改变它的值来改变动画效果
|
||||
*/
|
||||
protected int enterAnim = R.anim.fade;
|
||||
/**
|
||||
* 退出时该界面动画,可在finish();前通过改变它的值来改变动画效果
|
||||
*/
|
||||
protected int exitAnim = R.anim.right_push_out;
|
||||
|
||||
// /**通过id查找并获取控件,使用时不需要强转
|
||||
// * @param id
|
||||
// * @return
|
||||
// */
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public <V extends View> V findViewById(int id) {
|
||||
// return (V) view.findViewById(id);
|
||||
// }
|
||||
/**通过id查找并获取控件,并setOnClickListener
|
||||
* @param id
|
||||
* @param l
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <V extends View> V findViewById(int id, OnClickListener l) {
|
||||
V v = (V) findViewById(id);
|
||||
v.setOnClickListener(l);
|
||||
return v;
|
||||
}
|
||||
|
||||
//自动设置标题方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**自动把标题设置为上个Activity传入的INTENT_TITLE,建议在子类initView中使用
|
||||
* *这个方法没有return,tvTitle = tvBaseTitle,直接用tvBaseTitle
|
||||
* @must 在UI线程中调用
|
||||
*/
|
||||
protected void autoSetTitle() {
|
||||
tvBaseTitle = autoSetTitle(tvBaseTitle);
|
||||
}
|
||||
/**自动把标题设置为上个Activity传入的INTENT_TITLE,建议在子类initView中使用
|
||||
* @param tvTitle
|
||||
* @return tvTitle 返回tvTitle是为了可以写成一行,如 tvTitle = autoSetTitle((TextView) findViewById(titleResId));
|
||||
* @must 在UI线程中调用
|
||||
*/
|
||||
protected TextView autoSetTitle(TextView tvTitle) {
|
||||
if (tvTitle != null) {
|
||||
String title = getIntent().getStringExtra(INTENT_TITLE);
|
||||
if (StringUtil.isNotEmpty(title, false)) {
|
||||
tvTitle.setText(StringUtil.getString(title));
|
||||
}
|
||||
if (pbBaseTitle != null) {
|
||||
tvTitle.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (isShowingProgress() == false) {
|
||||
initData();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return tvTitle;
|
||||
}
|
||||
|
||||
//自动设置标题方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//显示与关闭进度弹窗方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**正在显示进度
|
||||
* @return
|
||||
*/
|
||||
public boolean isShowingProgress() {
|
||||
if (pbBaseTitle != null) {
|
||||
return pbBaseTitle.getVisibility() == View.VISIBLE;
|
||||
}
|
||||
if (progressDialog != null) {
|
||||
return progressDialog.isShowing();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 进度弹窗
|
||||
*/
|
||||
protected ProgressDialog progressDialog = null;
|
||||
|
||||
/**展示加载进度条,无标题
|
||||
* stringResId = R.string.loading
|
||||
*/
|
||||
public void showProgressDialog() {
|
||||
showProgressDialog(R.string.loading);
|
||||
}
|
||||
/**展示加载进度条,无标题
|
||||
* @param stringResId
|
||||
*/
|
||||
public void showProgressDialog(int stringResId) {
|
||||
try {
|
||||
showProgressDialog(null, context.getResources().getString(stringResId));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "showProgressDialog showProgressDialog(null, context.getResources().getString(stringResId));");
|
||||
}
|
||||
}
|
||||
/**展示加载进度条,无标题
|
||||
* @param message
|
||||
*/
|
||||
public void showProgressDialog(String message) {
|
||||
showProgressDialog(null, message);
|
||||
}
|
||||
/**展示加载进度条
|
||||
* @param title 标题
|
||||
* @param message 信息
|
||||
*/
|
||||
public void showProgressDialog(final String title, final String message) {
|
||||
runUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (pbBaseTitle != null) {
|
||||
pbBaseTitle.setVisibility(View.VISIBLE);
|
||||
String s = tvBaseTitle == null ? null : StringUtil.isNotEmpty(message, false) ? message : title;
|
||||
if (StringUtil.isNotEmpty(s, true)) {
|
||||
tvBaseTitle.setText(s);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (progressDialog == null) {
|
||||
progressDialog = new ProgressDialog(context);
|
||||
}
|
||||
if(progressDialog.isShowing()) {
|
||||
progressDialog.dismiss();
|
||||
}
|
||||
if (StringUtil.isNotEmpty(title, false)) {
|
||||
progressDialog.setTitle(title);
|
||||
}
|
||||
if (StringUtil.isNotEmpty(message, false)) {
|
||||
progressDialog.setMessage(message);
|
||||
}
|
||||
progressDialog.setCanceledOnTouchOutside(false);
|
||||
progressDialog.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**隐藏加载进度
|
||||
*/
|
||||
public void dismissProgressDialog() {
|
||||
runUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (progressDialog != null && progressDialog.isShowing()) {
|
||||
progressDialog.dismiss();
|
||||
}
|
||||
|
||||
if (pbBaseTitle != null) {
|
||||
pbBaseTitle.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//显示与关闭进度弹窗方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//启动新Activity方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**打开新的Activity,向左滑入效果
|
||||
* @param intent
|
||||
*/
|
||||
public void toActivity(Intent intent) {
|
||||
toActivity(intent, true);
|
||||
}
|
||||
/**打开新的Activity
|
||||
* @param intent
|
||||
* @param showAnimation
|
||||
*/
|
||||
public void toActivity(Intent intent, boolean showAnimation) {
|
||||
toActivity(intent, -1, showAnimation);
|
||||
}
|
||||
/**打开新的Activity,向左滑入效果
|
||||
* @param intent
|
||||
* @param requestCode
|
||||
*/
|
||||
public void toActivity(Intent intent, int requestCode) {
|
||||
toActivity(intent, requestCode, true);
|
||||
}
|
||||
/**打开新的Activity
|
||||
* @param intent
|
||||
* @param requestCode
|
||||
* @param showAnimation
|
||||
*/
|
||||
public void toActivity(final Intent intent, final int requestCode, final boolean showAnimation) {
|
||||
runUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (intent == null) {
|
||||
Log.w(TAG, "toActivity intent == null >> return;");
|
||||
return;
|
||||
}
|
||||
//fragment中使用context.startActivity会导致在fragment中不能正常接收onActivityResult
|
||||
if (requestCode < 0) {
|
||||
startActivity(intent);
|
||||
} else {
|
||||
startActivityForResult(intent, requestCode);
|
||||
}
|
||||
if (showAnimation) {
|
||||
overridePendingTransition(R.anim.right_push_in, R.anim.hold);
|
||||
} else {
|
||||
overridePendingTransition(R.anim.null_anim, R.anim.null_anim);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//启动新Activity方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//show short toast 方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
|
||||
* @param stringResId
|
||||
*/
|
||||
public void showShortToast(int stringResId) {
|
||||
try {
|
||||
showShortToast(context.getResources().getString(stringResId));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "showShortToast context.getResources().getString(resId)" +
|
||||
" >> catch (Exception e) {" + e.getMessage());
|
||||
}
|
||||
}
|
||||
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
|
||||
* @param string
|
||||
*/
|
||||
public void showShortToast(String string) {
|
||||
showShortToast(string, false);
|
||||
}
|
||||
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
|
||||
* @param string
|
||||
* @param isForceDismissProgressDialog
|
||||
*/
|
||||
public void showShortToast(final String string, final boolean isForceDismissProgressDialog) {
|
||||
runUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isForceDismissProgressDialog) {
|
||||
dismissProgressDialog();
|
||||
}
|
||||
Toast.makeText(context, "" + string, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
//show short toast 方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
//运行线程 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**在UI线程中运行,建议用这个方法代替runOnUiThread
|
||||
* @param action
|
||||
*/
|
||||
public final void runUiThread(Runnable action) {
|
||||
if (isAlive() == false) {
|
||||
Log.w(TAG, "runUiThread isAlive() == false >> return;");
|
||||
return;
|
||||
}
|
||||
runOnUiThread(action);
|
||||
}
|
||||
/**
|
||||
* 线程名列表
|
||||
*/
|
||||
protected List<String> threadNameList;
|
||||
/**运行线程
|
||||
* @param name
|
||||
* @param runnable
|
||||
* @return
|
||||
*/
|
||||
public final Handler runThread(String name, Runnable runnable) {
|
||||
if (isAlive() == false) {
|
||||
Log.w(TAG, "runThread isAlive() == false >> return null;");
|
||||
return null;
|
||||
}
|
||||
name = StringUtil.getTrimedString(name);
|
||||
Handler handler = ThreadManager.getInstance().runThread(name, runnable);
|
||||
if (handler == null) {
|
||||
Log.e(TAG, "runThread handler == null >> return null;");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (threadNameList.contains(name) == false) {
|
||||
threadNameList.add(name);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
//运行线程 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
//Activity的返回按钮和底部弹窗的取消按钮几乎是必备,正好原生支持反射;而其它比如Fragment极少用到,也不支持反射<<<<<<<<<
|
||||
/**返回按钮被点击,默认处理是onBottomDragListener.onDragBottom(false),重写可自定义事件处理
|
||||
* @param v
|
||||
* @use layout.xml中的组件添加android:onClick="onReturnClick"即可
|
||||
* @warn 只能在Activity对应的contentView layout中使用;
|
||||
* *给对应View setOnClickListener会导致android:onClick="onReturnClick"失效
|
||||
*/
|
||||
@Override
|
||||
public void onReturnClick(View v) {
|
||||
Log.d(TAG, "onReturnClick >>>");
|
||||
if (onBottomDragListener != null) {
|
||||
onBottomDragListener.onDragBottom(false);
|
||||
} else {
|
||||
onBackPressed();//会从最外层子类调finish();BaseBottomWindow就是示例
|
||||
}
|
||||
}
|
||||
/**前进按钮被点击,默认处理是onBottomDragListener.onDragBottom(true),重写可自定义事件处理
|
||||
* @param v
|
||||
* @use layout.xml中的组件添加android:onClick="onForwardClick"即可
|
||||
* @warn 只能在Activity对应的contentView layout中使用;
|
||||
* *给对应View setOnClickListener会导致android:onClick="onForwardClick"失效
|
||||
*/
|
||||
@Override
|
||||
public void onForwardClick(View v) {
|
||||
Log.d(TAG, "onForwardClick >>>");
|
||||
if (onBottomDragListener != null) {
|
||||
onBottomDragListener.onDragBottom(true);
|
||||
}
|
||||
}
|
||||
//Activity常用导航栏右边按钮,而且底部弹窗BottomWindow的确定按钮是必备;而其它比如Fragment极少用到,也不支持反射>>>>>
|
||||
|
||||
|
||||
@Override
|
||||
public final boolean isAlive() {
|
||||
return isAlive && context != null;// & ! isFinishing();导致finish,onDestroy内runUiThread不可用
|
||||
}
|
||||
@Override
|
||||
public final boolean isRunning() {
|
||||
return isRunning & isAlive();
|
||||
}
|
||||
|
||||
/**一般用于对不支持的数据的处理,比如onCreate中获取到不能接受的id(id<=0)可以这样处理
|
||||
*/
|
||||
public void finishWithError(String error) {
|
||||
showShortToast(error);
|
||||
enterAnim = exitAnim = R.anim.null_anim;
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();//必须写在最前才能显示自定义动画
|
||||
runUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (enterAnim > 0 && exitAnim > 0) {
|
||||
try {
|
||||
overridePendingTransition(enterAnim, exitAnim);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "finish overridePendingTransition(enterAnim, exitAnim);" +
|
||||
" >> catch (Exception e) { " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
Log.d(TAG, "\n onResume <<<<<<<<<<<<<<<<<<<<<<<");
|
||||
super.onResume();
|
||||
isRunning = true;
|
||||
Log.d(TAG, "onResume >>>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
Log.d(TAG, "\n onPause <<<<<<<<<<<<<<<<<<<<<<<");
|
||||
super.onPause();
|
||||
isRunning = false;
|
||||
Log.d(TAG, "onPause >>>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
}
|
||||
|
||||
/**销毁并回收内存
|
||||
* @warn 子类如果要使用这个方法内用到的变量,应重写onDestroy方法并在super.onDestroy();前操作
|
||||
*/
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
Log.d(TAG, "\n onDestroy <<<<<<<<<<<<<<<<<<<<<<<");
|
||||
dismissProgressDialog();
|
||||
BaseBroadcastReceiver.unregister(context, receiver);
|
||||
ThreadManager.getInstance().destroyThread(threadNameList);
|
||||
if (view != null) {
|
||||
try {
|
||||
view.destroyDrawingCache();
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "onDestroy try { view.destroyDrawingCache();" +
|
||||
" >> } catch (Exception e) {\n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
isAlive = false;
|
||||
isRunning = false;
|
||||
super.onDestroy();
|
||||
|
||||
inflater = null;
|
||||
view = null;
|
||||
pbBaseTitle = null;
|
||||
tvBaseTitle = null;
|
||||
|
||||
fragmentManager = null;
|
||||
progressDialog = null;
|
||||
threadNameList = null;
|
||||
|
||||
intent = null;
|
||||
|
||||
context = null;
|
||||
|
||||
Log.d(TAG, "onDestroy >>>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent == null ? null : intent.getAction();
|
||||
if (isAlive() == false || StringUtil.isNotEmpty(action, true) == false) {
|
||||
Log.e(TAG, "receiver.onReceive isAlive() == false" +
|
||||
" || StringUtil.isNotEmpty(action, true) == false >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ACTION_EXIT_APP.equals(action)) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//手机返回键和菜单键实现同点击标题栏左右按钮效果<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private boolean isOnKeyLongPress = false;
|
||||
@Override
|
||||
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
|
||||
isOnKeyLongPress = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (isOnKeyLongPress) {
|
||||
isOnKeyLongPress = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
if (onBottomDragListener != null) {
|
||||
onBottomDragListener.onDragBottom(false);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case KeyEvent.KEYCODE_MENU:
|
||||
if (onBottomDragListener != null) {
|
||||
onBottomDragListener.onDragBottom(true);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
//手机返回键和菜单键实现同点击标题栏左右按钮效果>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//底部滑动实现同点击标题栏左右按钮效果<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public void onShowPress(MotionEvent e) {
|
||||
}
|
||||
@Override
|
||||
public boolean onSingleTapUp(MotionEvent e) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e) {
|
||||
}
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
|
||||
// /*原来实现全局滑动返回的代码,OnFinishListener已删除,可以自己写一个或者
|
||||
// * 用onBottomDragListener.onDragBottom(false);代替onFinishListener.finish();**/
|
||||
// if (onFinishListener != null) {
|
||||
//
|
||||
// float maxDragHeight = getResources().getDimension(R.dimen.page_drag_max_height);
|
||||
// float distanceY = e2.getRawY() - e1.getRawY();
|
||||
// if (distanceY < maxDragHeight && distanceY > - maxDragHeight) {
|
||||
//
|
||||
// float minDragWidth = getResources().getDimension(R.dimen.page_drag_min_width);
|
||||
// float distanceX = e2.getRawX() - e1.getRawX();
|
||||
// if (distanceX > minDragWidth) {
|
||||
// onFinishListener.finish();
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
//底部滑动实现同点击标题栏左右按钮效果
|
||||
if (onBottomDragListener != null && e1.getRawY() > ScreenUtil.getScreenSize(this)[1]
|
||||
- ((int) getResources().getDimension(R.dimen.bottom_drag_height))) {
|
||||
|
||||
float maxDragHeight = getResources().getDimension(R.dimen.bottom_drag_max_height);
|
||||
float distanceY = e2.getRawY() - e1.getRawY();
|
||||
if (distanceY < maxDragHeight && distanceY > - maxDragHeight) {
|
||||
|
||||
float minDragWidth = getResources().getDimension(R.dimen.bottom_drag_min_width);
|
||||
float distanceX = e2.getRawX() - e1.getRawX();
|
||||
if (distanceX > minDragWidth) {
|
||||
onBottomDragListener.onDragBottom(false);
|
||||
return true;
|
||||
} else if (distanceX < - minDragWidth) {
|
||||
onBottomDragListener.onDragBottom(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
if (gestureDetector != null) {
|
||||
gestureDetector.onTouchEvent(ev);
|
||||
}
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
//底部滑动实现同点击标题栏左右按钮效果>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.interfaces.OnReachViewBorderListener;
|
||||
import zuo.biao.library.util.CommonUtil;
|
||||
import zuo.biao.library.util.SettingUtil;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**基础Adapter
|
||||
* <br> 适用于ListView,GridView等AbsListView的子类
|
||||
* @author Lemon
|
||||
* @warn 出于性能考虑,里面很多方法对变量(比如list)都没有判断,应在adapter外判断
|
||||
* @param <T> 数据模型(model/JavaBean)类
|
||||
* @use extends BaseAdapter<T>, 具体参考.DemoAdapter
|
||||
* <br> 预加载使用:
|
||||
* <br> 1.在子类getView中最后 return super.getView(position, convertView, parent);//非必须,只在预加载用到
|
||||
* <br> 2.在使用子类的类中调用子类setOnReachViewBorderListener方法(这个方法就在这个类)//非必须
|
||||
*/
|
||||
public abstract class BaseAdapter<T> extends android.widget.BaseAdapter {
|
||||
// private static final String TAG = "BaseAdapter";
|
||||
|
||||
|
||||
/**
|
||||
* 管理整个界面的Activity实例
|
||||
*/
|
||||
public Activity context;
|
||||
/**
|
||||
* 布局解释器,用来实例化列表的item的界面
|
||||
*/
|
||||
public LayoutInflater inflater;
|
||||
/**
|
||||
* 资源获取器,用于获取res目录下的文件及文件中的内容等
|
||||
*/
|
||||
public Resources resources;
|
||||
public BaseAdapter(Activity context) {
|
||||
this.context = context;
|
||||
|
||||
inflater = context.getLayoutInflater();
|
||||
resources = context.getResources();
|
||||
}
|
||||
|
||||
/**
|
||||
* 传进来的数据列表
|
||||
*/
|
||||
public List<T> list;
|
||||
public List<T> getList() {
|
||||
return list;
|
||||
}
|
||||
/**刷新列表
|
||||
*/
|
||||
public synchronized void refresh(List<T> list) {
|
||||
this.list = list == null ? null : new ArrayList<T>(list);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return list == null ? 0 : list.size();
|
||||
}
|
||||
/**获取item数据
|
||||
*/
|
||||
@Override
|
||||
public T getItem(int position) {
|
||||
return list.get(position);
|
||||
}
|
||||
/**获取item的id,如果不能满足需求可在子类重写
|
||||
* @param position
|
||||
* @return position
|
||||
*/
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
//预加载,可不使用 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
protected OnReachViewBorderListener onReachViewBorderListener;
|
||||
/**设置到达parent的边界的监听
|
||||
* @param onReachViewBorderListener
|
||||
*/
|
||||
public void setOnReachViewBorderListener(OnReachViewBorderListener onReachViewBorderListener) {
|
||||
this.onReachViewBorderListener = onReachViewBorderListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预加载提前数。
|
||||
* <br > = 0 - 列表滚到底部(最后一个Item View显示)时加载更多
|
||||
* <br > < 0 - 禁用加载更多
|
||||
* <br > > 0 - 列表滚到倒数第preloadCount个Item View显示时加载更多
|
||||
* @use 可在子类getView被调用前(可以是在构造器内)赋值
|
||||
*/
|
||||
protected int preloadCount = 0;
|
||||
|
||||
/**获取item对应View的方法,带item滑到底部等监听
|
||||
* @param position
|
||||
* @param convertView
|
||||
* @param parent
|
||||
* @return
|
||||
* @use 子类的getView中最后 return super.getView(position, convertView, parent);
|
||||
*/
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
if (SettingUtil.preload && onReachViewBorderListener != null && position >= getCount() - 1 - preloadCount) {
|
||||
onReachViewBorderListener.onReach(OnReachViewBorderListener.TYPE_BOTTOM, parent);
|
||||
}
|
||||
return convertView;
|
||||
}
|
||||
|
||||
//预加载,可不使用 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
//show short toast 方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
|
||||
* @param stringResId
|
||||
*/
|
||||
public void showShortToast(int stringResId) {
|
||||
CommonUtil.showShortToast(context, stringResId);
|
||||
}
|
||||
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
|
||||
* @param string
|
||||
*/
|
||||
public void showShortToast(String string) {
|
||||
CommonUtil.showShortToast(context, string);
|
||||
}
|
||||
//show short toast 方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//启动新Activity方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**打开新的Activity,向左滑入效果
|
||||
* @param intent
|
||||
*/
|
||||
public void toActivity(final Intent intent) {
|
||||
CommonUtil.toActivity(context, intent);
|
||||
}
|
||||
/**打开新的Activity
|
||||
* @param intent
|
||||
* @param showAnimation
|
||||
*/
|
||||
public void toActivity(final Intent intent, final boolean showAnimation) {
|
||||
CommonUtil.toActivity(context, intent, showAnimation);
|
||||
}
|
||||
/**打开新的Activity,向左滑入效果
|
||||
* @param intent
|
||||
* @param requestCode
|
||||
*/
|
||||
public void toActivity(final Intent intent, final int requestCode) {
|
||||
CommonUtil.toActivity(context, intent, requestCode);
|
||||
}
|
||||
/**打开新的Activity
|
||||
* @param intent
|
||||
* @param requestCode
|
||||
* @param showAnimation
|
||||
*/
|
||||
public void toActivity(final Intent intent, final int requestCode, final boolean showAnimation) {
|
||||
CommonUtil.toActivity(context, intent, requestCode, showAnimation);
|
||||
}
|
||||
//启动新Activity方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.util.DataKeeper;
|
||||
import zuo.biao.library.util.ImageLoaderUtil;
|
||||
import zuo.biao.library.util.Log;
|
||||
import zuo.biao.library.util.SettingUtil;
|
||||
import android.app.Application;
|
||||
|
||||
/**基础Application
|
||||
* @author Lemon
|
||||
* @see #init
|
||||
* @use extends BaseApplication 或 在你的Application的onCreate方法中BaseApplication.init(this);
|
||||
*/
|
||||
public class BaseApplication extends Application {
|
||||
private static final String TAG = "BaseApplication";
|
||||
|
||||
public BaseApplication() {
|
||||
}
|
||||
|
||||
private static Application instance;
|
||||
public static Application getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Log.d(TAG, "项目启动 >>>>>>>>>>>>>>>>>>>> \n\n");
|
||||
|
||||
init(this);
|
||||
}
|
||||
|
||||
/**初始化方法
|
||||
* @param application
|
||||
* @must 调用init方法且只能调用一次,如果extends BaseApplication会自动调用
|
||||
*/
|
||||
public static void init(Application application) {
|
||||
instance = application;
|
||||
if (instance == null) {
|
||||
Log.e(TAG, "\n\n\n\n\n !!!!!! 调用BaseApplication中的init方法,instance不能为null !!!" +
|
||||
"\n <<<<<< init instance == null !!! >>>>>>>> \n\n\n\n");
|
||||
}
|
||||
|
||||
DataKeeper.init(instance);
|
||||
SettingUtil.init(instance);
|
||||
ImageLoaderUtil.init(instance);
|
||||
}
|
||||
|
||||
/**获取应用名
|
||||
* @return
|
||||
*/
|
||||
public String getAppName() {
|
||||
return getResources().getString(R.string.app_name);
|
||||
}
|
||||
/**获取应用版本名(显示给用户看的)
|
||||
* @return
|
||||
*/
|
||||
public String getAppVersion() {
|
||||
return getResources().getString(R.string.app_version);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,276 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import zuo.biao.library.util.Log;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
|
||||
/**基础底部标签Activity
|
||||
* @author Lemon
|
||||
* @use extends BaseBottomTabActivity
|
||||
*/
|
||||
public abstract class BaseBottomTabActivity extends BaseActivity {
|
||||
private static final String TAG = "BaseBottomTabActivity";
|
||||
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
protected static int[] tabClickIds;
|
||||
|
||||
protected View[] vTabClickViews;
|
||||
protected View[][] vTabSelectViews;
|
||||
@Override
|
||||
public void initView() {// 必须调用
|
||||
|
||||
tabClickIds = getTabClickIds();
|
||||
|
||||
vTabClickViews = new View[getCount()];
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
vTabClickViews[i] = findViewById(tabClickIds[i]);
|
||||
}
|
||||
|
||||
int[][] tabSelectIds = getTabSelectIds();
|
||||
if (tabSelectIds != null && tabSelectIds.length > 0) {
|
||||
vTabSelectViews = new View[tabSelectIds.length][getCount()];
|
||||
for (int i = 0; i < tabSelectIds.length; i++) {
|
||||
if (tabSelectIds[i] != null) {
|
||||
for (int j = 0; j < tabSelectIds[i].length; j++) {
|
||||
vTabSelectViews[i][j] = findViewById(tabSelectIds[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**选择tab,在selectFragment里被调用
|
||||
* @param position
|
||||
*/
|
||||
protected abstract void selectTab(int position);
|
||||
|
||||
/**设置选中状态
|
||||
* @param position
|
||||
*/
|
||||
protected void setTabSelection(int position) {
|
||||
if (vTabSelectViews == null) {
|
||||
Log.e(TAG, "setTabSelection vTabSelectViews == null >> return;");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < vTabSelectViews.length; i++) {
|
||||
if (vTabSelectViews[i] == null) {
|
||||
Log.w(TAG, "setTabSelection vTabSelectViews[" + i + "] == null >> continue;");
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < vTabSelectViews[i].length; j++) {
|
||||
vTabSelectViews[i][j].setSelected(j == position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int currentPosition = 0;
|
||||
/**选择并显示fragment
|
||||
* @param position
|
||||
*/
|
||||
public void selectFragment(int position) {
|
||||
if (fragments == null || fragments.length != getCount()) {
|
||||
removeAll();
|
||||
fragments = new Fragment[getCount()];
|
||||
}
|
||||
|
||||
if (currentPosition == position) {
|
||||
if (fragments[position] != null && fragments[position].isVisible()) {
|
||||
Log.e(TAG, "selectFragment currentPosition == position" +
|
||||
" >> fragments[position] != null && fragments[position].isVisible()" +
|
||||
" >> return; ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (fragments[position] == null) {
|
||||
fragments[position] = getFragment(position);
|
||||
}
|
||||
|
||||
// 用全局的fragmentTransaction因为already committed 崩溃
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
fragmentTransaction.hide(fragments[currentPosition]);
|
||||
if (fragments[position].isAdded() == false) {
|
||||
fragmentTransaction.add(getFragmentContainerResId(), fragments[position]);
|
||||
}
|
||||
fragmentTransaction.show(fragments[position]).commit();
|
||||
|
||||
//消耗资源很少,不像Fragment<<<<<<
|
||||
setTabSelection(position);
|
||||
selectTab(position);
|
||||
//消耗资源很少,不像Fragment>>>>>>
|
||||
|
||||
this.currentPosition = position;
|
||||
};
|
||||
|
||||
|
||||
protected void reload(int position) {
|
||||
remove(position);
|
||||
if (position == currentPosition) {
|
||||
selectFragment(position);
|
||||
}
|
||||
}
|
||||
protected void reloadAll() {
|
||||
runUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
removeAll(true);
|
||||
selectFragment(currentPosition);
|
||||
}
|
||||
});
|
||||
}
|
||||
protected void remove(int position) {
|
||||
remove(position, false);
|
||||
}
|
||||
protected void remove(int position, boolean destroy) {
|
||||
if (fragments != null && position >= 0 && position < fragments.length && fragments[position] != null) {
|
||||
try {
|
||||
fragmentManager.beginTransaction().remove(fragments[position]).commit();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "remove try { fragmentManager.beginTransaction().remove(fragments[position]).commit();" +
|
||||
" } catch (Exception e) {\n" + e.getMessage());
|
||||
destroy = true;
|
||||
}
|
||||
if (destroy) {
|
||||
fragments[position].onDestroy();
|
||||
fragments[position] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected void removeAll() {
|
||||
removeAll(false);
|
||||
}
|
||||
protected void removeAll(boolean destroy) {
|
||||
if (fragments != null) {
|
||||
for (int i = 0; i < fragments.length; i++) {
|
||||
remove(i, destroy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
protected Fragment[] fragments;
|
||||
@Override
|
||||
public void initData() {// 必须调用
|
||||
|
||||
// fragmentActivity子界面初始化<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
selectFragment(currentPosition);
|
||||
|
||||
// fragmentActivity子界面初始化>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**获取tab内设置点击事件的View的id
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
protected abstract int[] getTabClickIds();
|
||||
|
||||
/**获取tab内设置选择事件的View的id,setSelected(position == currentPositon)
|
||||
* @return
|
||||
* @warn 返回int[leghth0][leghth1]必须满足leghth0 >= 1 && leghth1 = getCount() = getTabClickIds().length
|
||||
*/
|
||||
protected abstract int[][] getTabSelectIds();
|
||||
|
||||
/**获取Fragment容器的id
|
||||
* @return
|
||||
*/
|
||||
public abstract int getFragmentContainerResId();
|
||||
|
||||
/**获取新的Fragment
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
protected abstract Fragment getFragment(int position);
|
||||
|
||||
/**获取Tab(或Fragment)的数量
|
||||
* @return
|
||||
*/
|
||||
public int getCount() {
|
||||
return tabClickIds == null ? 0 :tabClickIds.length;
|
||||
}
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {// 必须调用
|
||||
|
||||
for (int i = 0; i < vTabClickViews.length; i++) {
|
||||
final int which = i;
|
||||
vTabClickViews[which].setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
selectFragment(which);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
// 类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
// 类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
// 系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// 内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
// 内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.util.Log;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.view.View;
|
||||
import android.view.animation.AnimationUtils;
|
||||
|
||||
/**基础底部弹出界面Activity
|
||||
* @author Lemon
|
||||
* @warn 不要在子类重复这个类中onCreate中的代码
|
||||
* @use extends BaseBottomWindow, 具体参考.DemoBottomWindow
|
||||
*/
|
||||
public abstract class BaseBottomWindow extends BaseActivity {
|
||||
private static final String TAG = "BaseBottomWindow";
|
||||
|
||||
public static final String INTENT_ITEMS = "INTENT_ITEMS";
|
||||
public static final String INTENT_ITEM_IDS = "INTENT_ITEM_IDS";
|
||||
|
||||
public static final String RESULT_TITLE = "RESULT_TITLE";
|
||||
public static final String RESULT_ITEM = "RESULT_ITEM";
|
||||
public static final String RESULT_ITEM_ID = "RESULT_ITEM_ID";
|
||||
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
protected View vBaseBottomWindowRoot;//子Activity全局背景View
|
||||
/**
|
||||
* 如果在子类中调用(即super.initView());则view必须含有initView中初始化用到的id(非@Nullable标记)且id对应的View的类型全部相同;
|
||||
* 否则必须在子类initView中重写这个类中initView内的代码(所有id替换成可用id)
|
||||
*/
|
||||
@Override
|
||||
public void initView() {// 必须调用
|
||||
enterAnim = exitAnim = R.anim.null_anim;
|
||||
|
||||
vBaseBottomWindowRoot = findViewById(R.id.vBaseBottomWindowRoot);
|
||||
|
||||
vBaseBottomWindowRoot.startAnimation(AnimationUtils.loadAnimation(context, R.anim.bottom_window_enter));
|
||||
}
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initData() {// 必须调用
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置需要返回的结果
|
||||
*/
|
||||
protected abstract void setResult();
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {// 必须调用
|
||||
|
||||
// vBaseBottomWindowRoot.setOnClickListener(new OnClickListener() {
|
||||
//
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// finish();
|
||||
// }
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onForwardClick(View v) {
|
||||
setResult();
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("HandlerLeak")
|
||||
public Handler exitHandler = new Handler(){
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
BaseBottomWindow.super.finish();
|
||||
}
|
||||
};
|
||||
|
||||
// 系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
// 类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private boolean isExit = false;
|
||||
/**带动画退出,并使退出事件只响应一次
|
||||
*/
|
||||
@Override
|
||||
public void finish() {
|
||||
Log.d(TAG, "finish >>> isExit = " + isExit);
|
||||
if (isExit) {
|
||||
return;
|
||||
}
|
||||
isExit = true;
|
||||
|
||||
vBaseBottomWindowRoot.startAnimation(AnimationUtils.loadAnimation(context, R.anim.bottom_window_exit));
|
||||
vBaseBottomWindowRoot.setVisibility(View.GONE);
|
||||
|
||||
exitHandler.sendEmptyMessageDelayed(0, 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
vBaseBottomWindowRoot = null;
|
||||
}
|
||||
|
||||
// 类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
// 系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// 内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
// 内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.util.Log;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
/**基础广播接收器
|
||||
* @author Lemon
|
||||
* @use 自定义BroadcastReceiver - extends BaseBroadcastReceiver;其它 - 直接使用里面的静态方法
|
||||
* @must 调用register和unregister方法
|
||||
*/
|
||||
public abstract class BaseBroadcastReceiver extends BroadcastReceiver {
|
||||
private static final String TAG = "BaseBroadcastReceiver";
|
||||
|
||||
/**接收信息监听回调
|
||||
*/
|
||||
public interface OnReceiveListener{
|
||||
void onReceive(Context context, Intent intent);
|
||||
}
|
||||
protected OnReceiveListener onReceiveListener = null;
|
||||
/**注册接收信息监听
|
||||
* @must 在register后,unregister前调用
|
||||
* @param onReceiveListener
|
||||
*/
|
||||
public void setOnReceiveListener(OnReceiveListener onReceiveListener) {
|
||||
this.onReceiveListener = onReceiveListener;
|
||||
}
|
||||
|
||||
|
||||
protected Context context = null;
|
||||
public BaseBroadcastReceiver(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**接收信息监听回调方法
|
||||
*/
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.i(TAG, "onReceive intent = " + intent);
|
||||
if (onReceiveListener != null) {
|
||||
onReceiveListener.onReceive(context, intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 注册广播接收器
|
||||
* @use 一般在Activity或Fragment的onCreate中调用
|
||||
*/
|
||||
public abstract BaseBroadcastReceiver register();
|
||||
/**
|
||||
* 取消注册广播接收器
|
||||
* @use 一般在Activity或Fragment的onDestroy中调用
|
||||
*/
|
||||
public abstract void unregister();
|
||||
|
||||
|
||||
/**注册广播接收器
|
||||
* @param context
|
||||
* @param receiver
|
||||
* @param action
|
||||
* @return
|
||||
*/
|
||||
public static BroadcastReceiver register(Context context, @Nullable BroadcastReceiver receiver, String action) {
|
||||
return register(context, receiver, new String[] {action});
|
||||
}
|
||||
/**注册广播接收器
|
||||
* @param context
|
||||
* @param receiver
|
||||
* @param actions
|
||||
* @return
|
||||
*/
|
||||
public static BroadcastReceiver register(Context context, @Nullable BroadcastReceiver receiver, String[] actions) {
|
||||
return register(context, receiver, actions == null ? null : Arrays.asList(actions));
|
||||
}
|
||||
/**注册广播接收器
|
||||
* @param context
|
||||
* @param receiver
|
||||
* @param actionList
|
||||
* @return
|
||||
*/
|
||||
public static BroadcastReceiver register(Context context, @Nullable BroadcastReceiver receiver, List<String> actionList) {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
for (String action : actionList) {
|
||||
if (StringUtil.isNotEmpty(action, true)) {
|
||||
filter.addAction(StringUtil.getTrimedString(action));
|
||||
}
|
||||
}
|
||||
return register(context, receiver, filter);
|
||||
}
|
||||
/**注册广播接收器
|
||||
* @param context
|
||||
* @param receiver
|
||||
* @param filter
|
||||
* @return
|
||||
*/
|
||||
public static BroadcastReceiver register(Context context, @Nullable BroadcastReceiver receiver, IntentFilter filter) {
|
||||
Log.i(TAG, "register >>>");
|
||||
if (context == null || filter == null) {
|
||||
Log.e(TAG, "register context == null || filter == null >> return;");
|
||||
return receiver;
|
||||
}
|
||||
|
||||
context.registerReceiver(receiver, filter);
|
||||
|
||||
return receiver;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**取消注册广播接收器
|
||||
* @param context
|
||||
* @param receiver
|
||||
* @return
|
||||
*/
|
||||
public static void unregister(Context context, BroadcastReceiver receiver) {
|
||||
Log.i(TAG, "unregister >>>");
|
||||
if (context == null || receiver == null) {
|
||||
Log.e(TAG, "unregister context == null || receiver == null >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
context.unregisterReceiver(receiver);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "unregister try { context.unregisterReceiver(receiver);" +
|
||||
" } catch (Exception e) { \n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,377 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.interfaces.FragmentPresenter;
|
||||
import zuo.biao.library.util.Log;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**基础android.support.v4.app.Fragment,通过继承可获取或使用 里面创建的 组件 和 方法
|
||||
* @author Lemon
|
||||
* @see #context
|
||||
* @see #view
|
||||
* @see #onCreateView
|
||||
* @see #setContentView
|
||||
* @see #runUiThread
|
||||
* @see #runThread
|
||||
* @see #onDestroy
|
||||
* @use extends BaseFragment, 具体参考.DemoFragment
|
||||
*/
|
||||
public abstract class BaseFragment extends Fragment implements FragmentPresenter {
|
||||
private static final String TAG = "BaseFragment";
|
||||
|
||||
/**
|
||||
* 添加该Fragment的Activity
|
||||
* @warn 不能在子类中创建
|
||||
*/
|
||||
protected BaseActivity context = null;
|
||||
/**
|
||||
* 该Fragment全局视图
|
||||
* @must 非abstract子类的onCreateView中return view;
|
||||
* @warn 不能在子类中创建
|
||||
*/
|
||||
protected View view = null;
|
||||
/**
|
||||
* 布局解释器
|
||||
* @warn 不能在子类中创建
|
||||
*/
|
||||
protected LayoutInflater inflater = null;
|
||||
/**
|
||||
* 添加这个Fragment视图的布局
|
||||
* @warn 不能在子类中创建
|
||||
*/
|
||||
@Nullable
|
||||
protected ViewGroup container = null;
|
||||
|
||||
private boolean isAlive = false;
|
||||
private boolean isRunning = false;
|
||||
/**
|
||||
* @must 在非abstract子类的onCreateView中super.onCreateView且return view;
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
|
||||
context = (BaseActivity) getActivity();
|
||||
isAlive = true;
|
||||
|
||||
this.inflater = inflater;
|
||||
this.container = container;
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/**设置界面布局
|
||||
* @warn 最多调用一次
|
||||
* @param layoutResID
|
||||
* @use 在onCreateView后调用
|
||||
*/
|
||||
public void setContentView(int layoutResID) {
|
||||
setContentView(inflater.inflate(layoutResID, container, false));
|
||||
}
|
||||
/**设置界面布局
|
||||
* @warn 最多调用一次
|
||||
* @param view
|
||||
* @use 在onCreateView后调用
|
||||
*/
|
||||
public void setContentView(View v) {
|
||||
setContentView(v, null);
|
||||
}
|
||||
/**设置界面布局
|
||||
* @warn 最多调用一次
|
||||
* @param view
|
||||
* @param params
|
||||
* @use 在onCreateView后调用
|
||||
*/
|
||||
public void setContentView(View v, ViewGroup.LayoutParams params) {
|
||||
view = v;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 该Fragment在Activity添加的所有Fragment中的位置,通过ARGUMENT_POSITION设置
|
||||
* @must 只使用getPosition方法来获取position,保证position正确
|
||||
*/
|
||||
private int position = -1;
|
||||
/**获取该Fragment在Activity添加的所有Fragment中的位置
|
||||
*/
|
||||
public int getPosition() {
|
||||
if (position < 0) {
|
||||
argument = getArguments();
|
||||
if (argument != null) {
|
||||
position = argument.getInt(ARGUMENT_POSITION, position);
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* 可用于 打开activity与fragment,fragment与fragment之间的通讯(传值)等
|
||||
*/
|
||||
protected Bundle argument = null;
|
||||
/**
|
||||
* 可用于 打开activity以及activity之间的通讯(传值)等;一些通讯相关基本操作(打电话、发短信等)
|
||||
*/
|
||||
protected Intent intent = null;
|
||||
|
||||
|
||||
/**通过id查找并获取控件,使用时不需要强转
|
||||
* @warn 调用前必须调用setContentView
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <V extends View> V findViewById(int id) {
|
||||
return (V) view.findViewById(id);
|
||||
}
|
||||
/**通过id查找并获取控件,并setOnClickListener
|
||||
* @param id
|
||||
* @param l
|
||||
* @return
|
||||
*/
|
||||
public <V extends View> V findViewById(int id, OnClickListener l) {
|
||||
V v = findViewById(id);
|
||||
v.setOnClickListener(l);
|
||||
return v;
|
||||
}
|
||||
|
||||
public Intent getIntent() {
|
||||
return context.getIntent();
|
||||
}
|
||||
|
||||
//运行线程<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**在UI线程中运行,建议用这个方法代替runOnUiThread
|
||||
* @param action
|
||||
*/
|
||||
public final void runUiThread(Runnable action) {
|
||||
if (isAlive() == false) {
|
||||
Log.w(TAG, "runUiThread isAlive() == false >> return;");
|
||||
return;
|
||||
}
|
||||
context.runUiThread(action);
|
||||
}
|
||||
/**运行线程
|
||||
* @param name
|
||||
* @param runnable
|
||||
* @return
|
||||
*/
|
||||
public final Handler runThread(String name, Runnable runnable) {
|
||||
if (isAlive() == false) {
|
||||
Log.w(TAG, "runThread isAlive() == false >> return null;");
|
||||
return null;
|
||||
}
|
||||
return context.runThread(name + getPosition(), runnable);//name, runnable);同一Activity出现多个同名Fragment可能会出错
|
||||
}
|
||||
|
||||
//运行线程>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//进度弹窗<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
/**展示加载进度条,无标题
|
||||
* @param stringResId
|
||||
*/
|
||||
public void showProgressDialog(int stringResId){
|
||||
if (isAlive() == false) {
|
||||
Log.w(TAG, "showProgressDialog isAlive() == false >> return;");
|
||||
return;
|
||||
}
|
||||
context.showProgressDialog(context.getResources().getString(stringResId));
|
||||
}
|
||||
/**展示加载进度条,无标题
|
||||
* @param dialogMessage
|
||||
*/
|
||||
public void showProgressDialog(String dialogMessage){
|
||||
if (isAlive() == false) {
|
||||
Log.w(TAG, "showProgressDialog isAlive() == false >> return;");
|
||||
return;
|
||||
}
|
||||
context.showProgressDialog(dialogMessage);
|
||||
}
|
||||
/**展示加载进度条
|
||||
* @param dialogTitle 标题
|
||||
* @param dialogMessage 信息
|
||||
*/
|
||||
public void showProgressDialog(String dialogTitle, String dialogMessage){
|
||||
if (isAlive() == false) {
|
||||
Log.w(TAG, "showProgressDialog isAlive() == false >> return;");
|
||||
return;
|
||||
}
|
||||
context.showProgressDialog(dialogTitle, dialogMessage);
|
||||
}
|
||||
|
||||
/** 隐藏加载进度
|
||||
*/
|
||||
public void dismissProgressDialog(){
|
||||
if (isAlive() == false) {
|
||||
Log.w(TAG, "dismissProgressDialog isAlive() == false >> return;");
|
||||
return;
|
||||
}
|
||||
context.dismissProgressDialog();
|
||||
}
|
||||
//进度弹窗>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//启动Activity<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**打开新的Activity,向左滑入效果
|
||||
* @param intent
|
||||
*/
|
||||
public void toActivity(Intent intent) {
|
||||
toActivity(intent, true);
|
||||
}
|
||||
/**打开新的Activity
|
||||
* @param intent
|
||||
* @param showAnimation
|
||||
*/
|
||||
public void toActivity(Intent intent, boolean showAnimation) {
|
||||
toActivity(intent, -1, showAnimation);
|
||||
}
|
||||
/**打开新的Activity,向左滑入效果
|
||||
* @param intent
|
||||
* @param requestCode
|
||||
*/
|
||||
public void toActivity(Intent intent, int requestCode) {
|
||||
toActivity(intent, requestCode, true);
|
||||
}
|
||||
/**打开新的Activity
|
||||
* @param intent
|
||||
* @param requestCode
|
||||
* @param showAnimation
|
||||
*/
|
||||
public void toActivity(final Intent intent, final int requestCode, final boolean showAnimation) {
|
||||
runUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (intent == null) {
|
||||
Log.w(TAG, "toActivity intent == null >> return;");
|
||||
return;
|
||||
}
|
||||
//fragment中使用context.startActivity会导致在fragment中不能正常接收onActivityResult
|
||||
if (requestCode < 0) {
|
||||
startActivity(intent);
|
||||
} else {
|
||||
startActivityForResult(intent, requestCode);
|
||||
}
|
||||
if (showAnimation) {
|
||||
context.overridePendingTransition(R.anim.right_push_in, R.anim.hold);
|
||||
} else {
|
||||
context.overridePendingTransition(R.anim.null_anim, R.anim.null_anim);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//启动Activity>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//show short toast<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
|
||||
* @param stringResId
|
||||
*/
|
||||
public void showShortToast(int stringResId) {
|
||||
if (isAlive() == false) {
|
||||
Log.w(TAG, "showProgressDialog isAlive() == false >> return;");
|
||||
return;
|
||||
}
|
||||
context.showShortToast(stringResId);
|
||||
}
|
||||
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
|
||||
* @param string
|
||||
*/
|
||||
public void showShortToast(String string) {
|
||||
if (isAlive() == false) {
|
||||
Log.w(TAG, "showProgressDialog isAlive() == false >> return;");
|
||||
return;
|
||||
}
|
||||
context.showShortToast(string);
|
||||
}
|
||||
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
|
||||
* @param string
|
||||
* @param isForceDismissProgressDialog
|
||||
*/
|
||||
public void showShortToast(String string, boolean isForceDismissProgressDialog) {
|
||||
if (isAlive() == false) {
|
||||
Log.w(TAG, "showProgressDialog isAlive() == false >> return;");
|
||||
return;
|
||||
}
|
||||
context.showShortToast(string, isForceDismissProgressDialog);
|
||||
}
|
||||
//show short toast>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
@Override
|
||||
public final boolean isAlive() {
|
||||
return isAlive && context != null;// & ! isRemoving();导致finish,onDestroy内runUiThread不可用
|
||||
}
|
||||
@Override
|
||||
public final boolean isRunning() {
|
||||
return isRunning & isAlive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
Log.d(TAG, "\n onResume <<<<<<<<<<<<<<<<<<<<<<<");
|
||||
super.onResume();
|
||||
isRunning = true;
|
||||
Log.d(TAG, "onResume >>>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
Log.d(TAG, "\n onPause <<<<<<<<<<<<<<<<<<<<<<<");
|
||||
super.onPause();
|
||||
isRunning = false;
|
||||
Log.d(TAG, "onPause >>>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
}
|
||||
|
||||
/**销毁并回收内存
|
||||
* @warn 子类如果要使用这个方法内用到的变量,应重写onDestroy方法并在super.onDestroy();前操作
|
||||
*/
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
Log.d(TAG, "\n onDestroy <<<<<<<<<<<<<<<<<<<<<<<");
|
||||
dismissProgressDialog();
|
||||
if (view != null) {
|
||||
try {
|
||||
view.destroyDrawingCache();
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "onDestroy try { view.destroyDrawingCache();" +
|
||||
" >> } catch (Exception e) {\n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
isAlive = false;
|
||||
isRunning = false;
|
||||
super.onDestroy();
|
||||
|
||||
view = null;
|
||||
inflater = null;
|
||||
container = null;
|
||||
|
||||
intent = null;
|
||||
argument = null;
|
||||
|
||||
context = null;
|
||||
|
||||
Log.d(TAG, "onDestroy >>>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
}
|
||||
}
|
@ -1,202 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.interfaces.AdapterCallBack;
|
||||
import zuo.biao.library.interfaces.OnReachViewBorderListener;
|
||||
import zuo.biao.library.interfaces.OnStopLoadListener;
|
||||
import zuo.biao.library.manager.HttpManager;
|
||||
import zuo.biao.library.ui.xlistview.XListView;
|
||||
import zuo.biao.library.ui.xlistview.XListView.IXListViewListener;
|
||||
import zuo.biao.library.util.Log;
|
||||
|
||||
/**基础http获取列表的Activity
|
||||
* @author Lemon
|
||||
* @param <T> 数据模型(model/JavaBean)类
|
||||
* @param <BA> 管理XListView的Adapter
|
||||
* @see #getListAsync(int)
|
||||
* @see #onHttpResponse(int, String, Exception)
|
||||
* @use extends BaseHttpListActivity 并在子类onCreate中lvBaseList.onRefresh();, 具体参考 .UserListFragment
|
||||
*/
|
||||
public abstract class BaseHttpListActivity<T, BA extends BaseAdapter> extends BaseListActivity<T, XListView, BA>
|
||||
implements HttpManager.OnHttpResponseListener, IXListViewListener, OnStopLoadListener {
|
||||
private static final String TAG = "BaseHttpListActivity";
|
||||
|
||||
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initView() {
|
||||
super.initView();
|
||||
|
||||
setList((List<T>) null);//ListView需要设置adapter才能显示header和footer; setAdapter调不到子类方法
|
||||
}
|
||||
|
||||
/**设置列表适配器
|
||||
* @param callBack
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void setList(AdapterCallBack<BA> callBack) {
|
||||
super.setList(callBack);
|
||||
boolean empty = adapter == null || adapter.isEmpty();
|
||||
Log.d(TAG, "setList adapter empty = " + empty);
|
||||
lvBaseList.showFooter(! empty);//放setAdapter中不行,adapter!=null时没有调用setAdapter
|
||||
|
||||
if (adapter != null && adapter instanceof zuo.biao.library.base.BaseAdapter) {
|
||||
((zuo.biao.library.base.BaseAdapter<T>) adapter).setOnReachViewBorderListener(
|
||||
empty || lvBaseList.isFooterShowing() == false ? null : new OnReachViewBorderListener(){
|
||||
|
||||
@Override
|
||||
public void onReach(int type, View v) {
|
||||
if (type == TYPE_BOTTOM) {
|
||||
lvBaseList.onLoadMore();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initData() {
|
||||
super.initData();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSON串转为List(已在非UI线程中)
|
||||
* *直接JSON.parseArray(json, getCacheClass());可以省去这个方法,但由于可能json不完全符合parseArray条件,所以还是要保留。
|
||||
* *比如json只有其中一部分能作为parseArray的字符串时,必须先提取出这段字符串再parseArray
|
||||
*/
|
||||
public abstract List<T> parseArray(String json);
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {// 必须调用
|
||||
super.initEvent();
|
||||
setOnStopLoadListener(this);
|
||||
|
||||
lvBaseList.setXListViewListener(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param page 用-page作为requestCode
|
||||
*/
|
||||
@Override
|
||||
public abstract void getListAsync(int page);
|
||||
|
||||
@Override
|
||||
public void onStopRefresh() {
|
||||
runUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
lvBaseList.stopRefresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onStopLoadMore(final boolean isHaveMore) {
|
||||
runUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
lvBaseList.stopLoadMore(isHaveMore);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requestCode = -page {@link #getListAsync(int)}
|
||||
* @param resultJson
|
||||
* @param e
|
||||
*/
|
||||
@Override
|
||||
public void onHttpResponse(final int requestCode, final String resultJson, final Exception e) {
|
||||
runThread(TAG + "onHttpResponse", new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int page = 0;
|
||||
if (requestCode > 0) {
|
||||
Log.w(TAG, "requestCode > 0, 应该用BaseListFragment#getListAsync(int page)中的page的负数作为requestCode!");
|
||||
} else {
|
||||
page = - requestCode;
|
||||
}
|
||||
List<T> array = parseArray(resultJson);
|
||||
|
||||
if ((array == null || array.isEmpty()) && e != null) {
|
||||
onLoadFailed(page, e);
|
||||
} else {
|
||||
onLoadSucceed(page, array);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
// 类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
// 类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
// 系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// 内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
// 内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,201 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.interfaces.AdapterCallBack;
|
||||
import zuo.biao.library.interfaces.OnReachViewBorderListener;
|
||||
import zuo.biao.library.interfaces.OnStopLoadListener;
|
||||
import zuo.biao.library.manager.HttpManager;
|
||||
import zuo.biao.library.ui.xlistview.XListView;
|
||||
import zuo.biao.library.ui.xlistview.XListView.IXListViewListener;
|
||||
import zuo.biao.library.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
/**基础http获取列表的Fragment
|
||||
* @author Lemon
|
||||
* @param <T> 数据模型(model/JavaBean)类
|
||||
* @param <BA> 管理XListView的Adapter
|
||||
* @see #getListAsync(int)
|
||||
* @see #onHttpResponse(int, String, Exception)
|
||||
* @use extends BaseHttpListFragment 并在子类onCreateView中lvBaseList.onRefresh();, 具体参考 .UserListFragment
|
||||
*/
|
||||
public abstract class BaseHttpListFragment<T, BA extends BaseAdapter> extends BaseListFragment<T, XListView, BA>
|
||||
implements HttpManager.OnHttpResponseListener, IXListViewListener, OnStopLoadListener {
|
||||
private static final String TAG = "BaseHttpListFragment";
|
||||
|
||||
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initView() {
|
||||
super.initView();
|
||||
|
||||
setList((List<T>) null);//ListView需要设置adapter才能显示header和footer; setAdapter调不到子类方法
|
||||
}
|
||||
|
||||
/**设置列表适配器
|
||||
* @param callBack
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void setList(AdapterCallBack<BA> callBack) {
|
||||
super.setList(callBack);
|
||||
boolean empty = adapter == null || adapter.isEmpty();
|
||||
Log.d(TAG, "setList adapter empty = " + empty);
|
||||
lvBaseList.showFooter(! empty);//放setAdapter中不行,adapter!=null时没有调用setAdapter
|
||||
|
||||
if (adapter != null && adapter instanceof zuo.biao.library.base.BaseAdapter) {
|
||||
((zuo.biao.library.base.BaseAdapter<T>) adapter).setOnReachViewBorderListener(
|
||||
empty || lvBaseList.isFooterShowing() == false ? null : new OnReachViewBorderListener(){
|
||||
|
||||
@Override
|
||||
public void onReach(int type, View v) {
|
||||
if (type == TYPE_BOTTOM) {
|
||||
lvBaseList.onLoadMore();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initData() {
|
||||
super.initData();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JSON串转为List(已在非UI线程中)
|
||||
* *直接JSON.parseArray(json, getCacheClass());可以省去这个方法,但由于可能json不完全符合parseArray条件,所以还是要保留。
|
||||
* *比如json只有其中一部分能作为parseArray的字符串时,必须先提取出这段字符串再parseArray
|
||||
*/
|
||||
public abstract List<T> parseArray(String json);
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {// 必须调用
|
||||
super.initEvent();
|
||||
setOnStopLoadListener(this);
|
||||
|
||||
lvBaseList.setXListViewListener(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param page 用-page作为requestCode
|
||||
*/
|
||||
@Override
|
||||
public abstract void getListAsync(int page);
|
||||
|
||||
@Override
|
||||
public void onStopRefresh() {
|
||||
runUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
lvBaseList.stopRefresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onStopLoadMore(final boolean isHaveMore) {
|
||||
runUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
lvBaseList.stopLoadMore(isHaveMore);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requestCode = -page {@link #getListAsync(int)}
|
||||
* @param resultJson
|
||||
* @param e
|
||||
*/
|
||||
@Override
|
||||
public void onHttpResponse(final int requestCode, final String resultJson, final Exception e) {
|
||||
runThread(TAG + "onHttpResponse", new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int page = 0;
|
||||
if (requestCode > 0) {
|
||||
Log.w(TAG, "requestCode > 0, 应该用BaseListFragment#getListAsync(int page)中的page的负数作为requestCode!");
|
||||
} else {
|
||||
page = - requestCode;
|
||||
}
|
||||
List<T> array = parseArray(resultJson);
|
||||
|
||||
if ((array == null || array.isEmpty()) && e != null) {
|
||||
onLoadFailed(page, e);
|
||||
} else {
|
||||
onLoadSucceed(page, array);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
// 类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
// 类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
// 系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// 内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
// 内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,443 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.interfaces.AdapterCallBack;
|
||||
import zuo.biao.library.interfaces.CacheCallBack;
|
||||
import zuo.biao.library.interfaces.OnStopLoadListener;
|
||||
import zuo.biao.library.manager.CacheManager;
|
||||
import zuo.biao.library.manager.HttpManager;
|
||||
import zuo.biao.library.util.Log;
|
||||
import zuo.biao.library.util.SettingUtil;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
/**基础列表Activity
|
||||
* @author Lemon
|
||||
* @param <T> 数据模型(model/JavaBean)类
|
||||
* @param <LV> AbsListView的子类(ListView,GridView等)
|
||||
* @param <BA> 管理LV的Adapter
|
||||
* @see #lvBaseList
|
||||
* @see #initCache
|
||||
* @see #initView
|
||||
* @see #getListAsync
|
||||
* @see #onRefresh
|
||||
* @use extends BaseListActivity 并在子类onCreate中调用onRefresh(...), 具体参考.DemoListActivity
|
||||
* *缓存使用:在initData前调用initCache(...), 具体参考 .DemoListActivity(onCreate方法内)
|
||||
*/
|
||||
public abstract class BaseListActivity<T, LV extends AbsListView, BA extends BaseAdapter> extends BaseActivity {
|
||||
private static final String TAG = "BaseListActivity";
|
||||
|
||||
private OnStopLoadListener onStopLoadListener;
|
||||
/**设置停止加载监听
|
||||
* @param onStopLoadListener
|
||||
*/
|
||||
protected void setOnStopLoadListener(OnStopLoadListener onStopLoadListener) {
|
||||
this.onStopLoadListener = onStopLoadListener;
|
||||
}
|
||||
|
||||
|
||||
private CacheCallBack<T> cacheCallBack;
|
||||
/**初始化缓存
|
||||
* @warn 在initData前使用才有效
|
||||
* @param cacheCallBack
|
||||
*/
|
||||
protected void initCache(CacheCallBack<T> cacheCallBack) {
|
||||
this.cacheCallBack = cacheCallBack;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**
|
||||
* 显示列表的ListView
|
||||
* @warn 只使用lvBaseList为显示列表数据的AbsListView(ListView,GridView等),不要在子类中改变它
|
||||
*/
|
||||
protected LV lvBaseList;
|
||||
/**
|
||||
* 管理LV的Item的Adapter
|
||||
*/
|
||||
protected BA adapter;
|
||||
/**
|
||||
* 如果在子类中调用(即super.initView());则view必须含有initView中初始化用到的id且id对应的View的类型全部相同;
|
||||
* 否则必须在子类initView中重写这个类中initView内的代码(所有id替换成可用id)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void initView() {// 必须调用
|
||||
|
||||
lvBaseList = (LV) findViewById(R.id.lvBaseList);
|
||||
}
|
||||
|
||||
/**设置adapter
|
||||
* @param adapter
|
||||
*/
|
||||
public void setAdapter(BA adapter) {
|
||||
this.adapter = adapter;
|
||||
lvBaseList.setAdapter(adapter);
|
||||
}
|
||||
|
||||
/**显示列表(已在UI线程中),一般需求建议直接调用setList(List<T> l, AdapterCallBack<BA> callBack)
|
||||
* @param list
|
||||
*/
|
||||
public abstract void setList(List<T> list);
|
||||
|
||||
/**显示列表(已在UI线程中)
|
||||
* @param list
|
||||
*/
|
||||
public void setList(AdapterCallBack<BA> callBack) {
|
||||
if (adapter == null) {
|
||||
setAdapter(callBack.createAdapter());
|
||||
}
|
||||
callBack.refreshAdapter();
|
||||
}
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private boolean isToSaveCache;
|
||||
private boolean isToLoadCache;
|
||||
@Override
|
||||
public void initData() {// 必须调用
|
||||
|
||||
isToSaveCache = SettingUtil.cache && cacheCallBack != null && cacheCallBack.getCacheClass() != null;
|
||||
isToLoadCache = isToSaveCache && StringUtil.isNotEmpty(cacheCallBack.getCacheGroup(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表,在非UI线程中
|
||||
* @must 获取成功后调用onLoadSucceed
|
||||
* @param page 在onLoadSucceed中传回来保证一致性
|
||||
*/
|
||||
public abstract void getListAsync(int page);
|
||||
|
||||
|
||||
|
||||
public void loadData(int page) {
|
||||
loadData(page, isToLoadCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
private List<T> list;
|
||||
/**
|
||||
* 正在加载
|
||||
*/
|
||||
protected boolean isLoading = false;
|
||||
/**
|
||||
* 还有更多可加载数据
|
||||
*/
|
||||
protected boolean isHaveMore = true;
|
||||
/**
|
||||
* 加载页码,每页对应一定数量的数据
|
||||
*/
|
||||
private int page;
|
||||
private int loadCacheStart;
|
||||
/**加载数据,用getListAsync方法发请求获取数据
|
||||
* @param page_
|
||||
* @param isCache
|
||||
*/
|
||||
private void loadData(int page_, final boolean isCache) {
|
||||
if (isLoading) {
|
||||
Log.w(TAG, "loadData isLoading >> return;");
|
||||
return;
|
||||
}
|
||||
isLoading = true;
|
||||
isSucceed = false;
|
||||
|
||||
if (page_ <= HttpManager.PAGE_NUM_0) {
|
||||
page_ = HttpManager.PAGE_NUM_0;
|
||||
isHaveMore = true;
|
||||
loadCacheStart = 0;//使用则可像网络正常情况下的重载,不使用则在网络异常情况下不重载(导致重载后加载数据下移)
|
||||
} else {
|
||||
if (isHaveMore == false) {
|
||||
stopLoadData(page_);
|
||||
return;
|
||||
}
|
||||
loadCacheStart = list == null ? 0 : list.size();
|
||||
}
|
||||
this.page = page_;
|
||||
Log.i(TAG, "loadData page_ = " + page_ + "; isCache = " + isCache
|
||||
+ "; isHaveMore = " + isHaveMore + "; loadCacheStart = " + loadCacheStart);
|
||||
|
||||
runThread(TAG + "loadData", new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (isCache == false) {//从网络获取数据
|
||||
getListAsync(page);
|
||||
} else {//从缓存获取数据
|
||||
onLoadSucceed(page, CacheManager.getInstance().getList(cacheCallBack.getCacheClass()
|
||||
, cacheCallBack.getCacheGroup(), loadCacheStart, cacheCallBack.getCacheCount()),
|
||||
true);
|
||||
if (page <= HttpManager.PAGE_NUM_0) {
|
||||
isLoading = false;//stopLoadeData在其它线程isLoading = false;后这个线程里还是true
|
||||
loadData(page, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**停止加载数据
|
||||
* isCache = false;
|
||||
* @param page
|
||||
*/
|
||||
public synchronized void stopLoadData(int page) {
|
||||
stopLoadData(page, false);
|
||||
}
|
||||
/**停止加载数据
|
||||
* @param page
|
||||
* @param isCache
|
||||
*/
|
||||
private synchronized void stopLoadData(int page, boolean isCache) {
|
||||
Log.i(TAG, "stopLoadData isCache = " + isCache);
|
||||
isLoading = false;
|
||||
dismissProgressDialog();
|
||||
|
||||
if (isCache) {
|
||||
Log.d(TAG, "stopLoadData isCache >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
if (onStopLoadListener == null) {
|
||||
Log.w(TAG, "stopLoadData onStopLoadListener == null >> return;");
|
||||
return;
|
||||
}
|
||||
onStopLoadListener.onStopRefresh();
|
||||
if (page > HttpManager.PAGE_NUM_0) {
|
||||
onStopLoadListener.onStopLoadMore(isHaveMore);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean isSucceed = false;
|
||||
/**处理列表
|
||||
* @param page
|
||||
* @param newList 新数据列表
|
||||
* @param isCache
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
public synchronized void handleList(int page, List<T> newList, boolean isCache) {
|
||||
if (newList == null) {
|
||||
newList = new ArrayList<T>();
|
||||
}
|
||||
isSucceed = ! newList.isEmpty();
|
||||
Log.i(TAG, "\n\n<<<<<<<<<<<<<<<<<\n handleList newList.size = " + newList.size() + "; isCache = " + isCache
|
||||
+ "; page = " + page + "; isSucceed = " + isSucceed);
|
||||
|
||||
if (page <= HttpManager.PAGE_NUM_0) {
|
||||
Log.i(TAG, "handleList page <= HttpManager.PAGE_NUM_0 >>>> ");
|
||||
saveCacheStart = 0;
|
||||
list = new ArrayList<T>(newList);
|
||||
if (isCache == false && list.isEmpty() == false) {
|
||||
Log.i(TAG, "handleList isCache == false && list.isEmpty() == false >> isToLoadCache = false;");
|
||||
isToLoadCache = false;
|
||||
}
|
||||
} else {
|
||||
Log.i(TAG, "handleList page > HttpManager.PAGE_NUM_0 >>>> ");
|
||||
if (list == null) {
|
||||
list = new ArrayList<T>();
|
||||
}
|
||||
saveCacheStart = list.size();
|
||||
isHaveMore = ! newList.isEmpty();
|
||||
if (isHaveMore) {
|
||||
list.addAll(newList);
|
||||
}
|
||||
}
|
||||
|
||||
Log.i(TAG, "handleList list.size = " + list.size() + "; isHaveMore = " + isHaveMore
|
||||
+ "; isToLoadCache = " + isToLoadCache + "; saveCacheStart = " + saveCacheStart
|
||||
+ "\n>>>>>>>>>>>>>>>>>>\n\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**加载成功
|
||||
* isCache = false;
|
||||
* @param page
|
||||
* @param newList
|
||||
*/
|
||||
public synchronized void onLoadSucceed(final int page, final List<T> newList) {
|
||||
onLoadSucceed(page, newList, false);
|
||||
}
|
||||
/**加载成功
|
||||
* @param page
|
||||
* @param newList
|
||||
* @param isCache newList是否为缓存
|
||||
*/
|
||||
private synchronized void onLoadSucceed(final int page, final List<T> newList, final boolean isCache) {
|
||||
runThread(TAG + "onLoadSucceed", new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(TAG, "onLoadSucceed page = " + page + "; isCache = " + isCache + " >> handleList...");
|
||||
handleList(page, newList, isCache);
|
||||
|
||||
runUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
stopLoadData(page, isCache);
|
||||
setList(list);
|
||||
}
|
||||
});
|
||||
|
||||
if (isToSaveCache && isCache == false) {
|
||||
saveCache(newList);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**加载失败
|
||||
* @param page
|
||||
* @param e
|
||||
*/
|
||||
public synchronized void onLoadFailed(int page, Exception e) {
|
||||
Log.e(TAG, "onLoadFailed page = " + page + "; e = " + (e == null ? null : e.getMessage()));
|
||||
stopLoadData(page);
|
||||
showShortToast(R.string.get_failed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//缓存<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
// /**
|
||||
// * 获取缓存每页数量
|
||||
// * @return > 0 ?缓存 : 不缓存
|
||||
// */
|
||||
// public int getCacheCount() {
|
||||
// //让给服务器返回每页数量为count的数据,不行的话在子类重写 Math.max(10, newList == null ? 0 : newList.size());
|
||||
// return CacheManager.MAX_PAGE_SIZE;
|
||||
// }
|
||||
|
||||
private int saveCacheStart;
|
||||
/**保存缓存
|
||||
* @param newList
|
||||
*/
|
||||
public synchronized void saveCache(List<T> newList) {
|
||||
if (cacheCallBack == null || newList == null || newList.isEmpty()) {
|
||||
Log.e(TAG, "saveCache cacheCallBack == null || newList == null || newList.isEmpty() >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
LinkedHashMap<String, T> map = new LinkedHashMap<String, T>();
|
||||
for (T data : newList) {
|
||||
if (data != null) {
|
||||
map.put(cacheCallBack.getCacheId(data), data);//map.put(null, data);不会崩溃
|
||||
}
|
||||
}
|
||||
|
||||
CacheManager.getInstance().saveList(cacheCallBack.getCacheClass(), cacheCallBack.getCacheGroup()
|
||||
, map, saveCacheStart, cacheCallBack.getCacheCount());
|
||||
}
|
||||
//缓存>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**刷新(从头加载)
|
||||
* @must 在子类onCreate中调用,建议放在最后
|
||||
*/
|
||||
public void onRefresh() {
|
||||
loadData(HttpManager.PAGE_NUM_0);
|
||||
}
|
||||
/**加载更多
|
||||
*/
|
||||
public void onLoadMore() {
|
||||
if (isSucceed == false && page <= HttpManager.PAGE_NUM_0) {
|
||||
Log.w(TAG, "onLoadMore isSucceed == false && page <= HttpManager.PAGE_NUM_0 >> return;");
|
||||
return;
|
||||
}
|
||||
loadData(page + (isSucceed ? 1 : 0));
|
||||
}
|
||||
|
||||
|
||||
// 系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
// 类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
isLoading = false;
|
||||
isHaveMore = false;
|
||||
isToSaveCache = false;
|
||||
isToLoadCache = false;
|
||||
|
||||
super.onDestroy();
|
||||
|
||||
lvBaseList = null;
|
||||
list = null;
|
||||
|
||||
onStopLoadListener = null;
|
||||
cacheCallBack = null;
|
||||
}
|
||||
|
||||
// 类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
// 系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// 内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
// 内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,510 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.interfaces.AdapterCallBack;
|
||||
import zuo.biao.library.interfaces.CacheCallBack;
|
||||
import zuo.biao.library.interfaces.OnStopLoadListener;
|
||||
import zuo.biao.library.manager.CacheManager;
|
||||
import zuo.biao.library.manager.HttpManager;
|
||||
import zuo.biao.library.util.Log;
|
||||
import zuo.biao.library.util.SettingUtil;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
/**基础列表Activity
|
||||
* @author Lemon
|
||||
* @param <T> 数据模型(model/JavaBean)类
|
||||
* @param <LV> AbsListView的子类(ListView,GridView等)
|
||||
* @param <BA> 管理LV的Adapter
|
||||
* @see #onCreateView
|
||||
* @see #setContentView
|
||||
* @see #lvBaseList
|
||||
* @see #initCache
|
||||
* @see #initView
|
||||
* @see #getListAsync
|
||||
* @see #onRefresh
|
||||
* @use extends BaseListFragment 并在子类onCreate中调用onRefresh(...), 具体参考.DemoListFragment
|
||||
* *缓存使用:在initData前调用initCache(...), 具体参考 .UserListFragment(onCreate方法内)
|
||||
*/
|
||||
public abstract class BaseListFragment<T, LV extends AbsListView, BA extends BaseAdapter> extends BaseFragment {
|
||||
private static final String TAG = "BaseListFragment";
|
||||
|
||||
private OnStopLoadListener onStopLoadListener;
|
||||
/**设置停止加载监听
|
||||
* @param onStopLoadListener
|
||||
*/
|
||||
protected void setOnStopLoadListener(OnStopLoadListener onStopLoadListener) {
|
||||
this.onStopLoadListener = onStopLoadListener;
|
||||
}
|
||||
|
||||
|
||||
private CacheCallBack<T> cacheCallBack;
|
||||
/**初始化缓存
|
||||
* @warn 在initData前使用才有效
|
||||
* @param cacheCallBack
|
||||
*/
|
||||
protected void initCache(CacheCallBack<T> cacheCallBack) {
|
||||
this.cacheCallBack = cacheCallBack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param inflater
|
||||
* @param container
|
||||
* @param savedInstanceState
|
||||
* @return
|
||||
* @must 1.不要在子类重复这个类中onCreateView中的代码;
|
||||
* 2.在子类onCreateView中super.onCreateView(inflater, container, savedInstanceState);
|
||||
* initView();initData();initEvent(); return view;
|
||||
*/
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return onCreateView(inflater, container, savedInstanceState, 0);
|
||||
}
|
||||
/**
|
||||
* @param inflater
|
||||
* @param container
|
||||
* @param savedInstanceState
|
||||
* @param layoutResID fragment全局视图view的布局资源id,默认值为R.layout.base_http_list_fragment
|
||||
* @return
|
||||
* @must 1.不要在子类重复这个类中onCreateView中的代码;
|
||||
* 2.在子类onCreateView中super.onCreateView(inflater, container, savedInstanceState, layoutResID);
|
||||
* initView();initData();initEvent(); return view;
|
||||
*/
|
||||
public final View onCreateView(LayoutInflater inflater, ViewGroup container
|
||||
, Bundle savedInstanceState, int layoutResID) {
|
||||
//类相关初始化,必须使用<<<<<<<<<<<<<<<<<<
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
//调用这个类的setContentView而崩溃 super.setContentView(layoutResID <= 0 ? R.layout.base_tab_activity : layoutResID);
|
||||
view = inflater.inflate(layoutResID <= 0 ? R.layout.base_list_fragment : layoutResID, container, false);
|
||||
//类相关初始化,必须使用>>>>>>>>>>>>>>>>
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
//防止子类中setContentView <<<<<<<<<<<<<<<<<<<<<<<<
|
||||
/**
|
||||
* @warn 不支持setContentView,传界面布局请使用onCreateView(Bundle savedInstanceState, int layoutResID)等方法
|
||||
*/
|
||||
@Override
|
||||
public final void setContentView(int layoutResID) {
|
||||
setContentView(null);
|
||||
}
|
||||
/**
|
||||
* @warn 不支持setContentView,传界面布局请使用onCreateView(Bundle savedInstanceState, int layoutResID)等方法
|
||||
*/
|
||||
@Override
|
||||
public final void setContentView(View view) {
|
||||
setContentView(null, null);
|
||||
}
|
||||
/**
|
||||
* @warn 不支持setContentView,传界面布局请使用onCreateView(Bundle savedInstanceState, int layoutResID)等方法
|
||||
*/
|
||||
@Override
|
||||
public final void setContentView(View view, LayoutParams params) {
|
||||
throw new UnsupportedOperationException(TAG + "不支持setContentView,传界面布局请使用onCreateView(" +
|
||||
"LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState, int layoutResID)等方法");
|
||||
}
|
||||
//防止子类中setContentView >>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**
|
||||
* 显示列表的ListView
|
||||
* @warn 只使用lvBaseList为显示列表数据的AbsListView(ListView,GridView等),不要在子类中改变它
|
||||
*/
|
||||
protected LV lvBaseList;
|
||||
/**
|
||||
* 管理LV的Item的Adapter
|
||||
*/
|
||||
protected BA adapter;
|
||||
/**
|
||||
* 如果在子类中调用(即super.initView());则view必须含有initView中初始化用到的id且id对应的View的类型全部相同;
|
||||
* 否则必须在子类initView中重写这个类中initView内的代码(所有id替换成可用id)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void initView() {// 必须调用
|
||||
|
||||
lvBaseList = (LV) findViewById(R.id.lvBaseList);
|
||||
}
|
||||
|
||||
/**设置adapter
|
||||
* @param adapter
|
||||
*/
|
||||
public void setAdapter(BA adapter) {
|
||||
this.adapter = adapter;
|
||||
lvBaseList.setAdapter(adapter);
|
||||
}
|
||||
|
||||
/**显示列表(已在UI线程中),一般需求建议直接调用setList(List<T> l, AdapterCallBack<BA> callBack)
|
||||
* @param list
|
||||
*/
|
||||
public abstract void setList(List<T> list);
|
||||
|
||||
/**显示列表(已在UI线程中)
|
||||
* @param callBack
|
||||
*/
|
||||
public void setList(AdapterCallBack<BA> callBack) {
|
||||
if (adapter == null) {
|
||||
setAdapter(callBack.createAdapter());
|
||||
}
|
||||
callBack.refreshAdapter();
|
||||
}
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private boolean isToSaveCache;
|
||||
private boolean isToLoadCache;
|
||||
@Override
|
||||
public void initData() {// 必须调用
|
||||
|
||||
isToSaveCache = SettingUtil.cache && cacheCallBack != null && cacheCallBack.getCacheClass() != null;
|
||||
isToLoadCache = isToSaveCache && StringUtil.isNotEmpty(cacheCallBack.getCacheGroup(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表,在非UI线程中
|
||||
* @must 获取成功后调用onLoadSucceed
|
||||
* @param page 在onLoadSucceed中传回来保证一致性
|
||||
*/
|
||||
public abstract void getListAsync(int page);
|
||||
|
||||
|
||||
|
||||
public void loadData(int page) {
|
||||
loadData(page, isToLoadCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
private List<T> list;
|
||||
/**
|
||||
* 正在加载
|
||||
*/
|
||||
protected boolean isLoading = false;
|
||||
/**
|
||||
* 还有更多可加载数据
|
||||
*/
|
||||
protected boolean isHaveMore = true;
|
||||
/**
|
||||
* 加载页码,每页对应一定数量的数据
|
||||
*/
|
||||
private int page;
|
||||
private int loadCacheStart;
|
||||
/**加载数据,用getListAsync方法发请求获取数据
|
||||
* @param page_
|
||||
* @param isCache
|
||||
*/
|
||||
private void loadData(int page_, final boolean isCache) {
|
||||
if (isLoading) {
|
||||
Log.w(TAG, "loadData isLoading >> return;");
|
||||
return;
|
||||
}
|
||||
isLoading = true;
|
||||
isSucceed = false;
|
||||
|
||||
if (page_ <= HttpManager.PAGE_NUM_0) {
|
||||
page_ = HttpManager.PAGE_NUM_0;
|
||||
isHaveMore = true;
|
||||
loadCacheStart = 0;//使用则可像网络正常情况下的重载,不使用则在网络异常情况下不重载(导致重载后加载数据下移)
|
||||
} else {
|
||||
if (isHaveMore == false) {
|
||||
stopLoadData(page_);
|
||||
return;
|
||||
}
|
||||
loadCacheStart = list == null ? 0 : list.size();
|
||||
}
|
||||
this.page = page_;
|
||||
Log.i(TAG, "loadData page_ = " + page_ + "; isCache = " + isCache
|
||||
+ "; isHaveMore = " + isHaveMore + "; loadCacheStart = " + loadCacheStart);
|
||||
|
||||
runThread(TAG + "loadData", new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (isCache == false) {//从网络获取数据
|
||||
getListAsync(page);
|
||||
} else {//从缓存获取数据
|
||||
onLoadSucceed(page, CacheManager.getInstance().getList(cacheCallBack.getCacheClass()
|
||||
, cacheCallBack.getCacheGroup(), loadCacheStart, cacheCallBack.getCacheCount()),
|
||||
true);
|
||||
if (page <= HttpManager.PAGE_NUM_0) {
|
||||
isLoading = false;//stopLoadeData在其它线程isLoading = false;后这个线程里还是true
|
||||
loadData(page, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**停止加载数据
|
||||
* isCache = false;
|
||||
* @param page
|
||||
*/
|
||||
public synchronized void stopLoadData(int page) {
|
||||
stopLoadData(page, false);
|
||||
}
|
||||
/**停止加载数据
|
||||
* @param page
|
||||
* @param isCache
|
||||
*/
|
||||
private synchronized void stopLoadData(int page, boolean isCache) {
|
||||
Log.i(TAG, "stopLoadData isCache = " + isCache);
|
||||
isLoading = false;
|
||||
dismissProgressDialog();
|
||||
|
||||
if (isCache) {
|
||||
Log.d(TAG, "stopLoadData isCache >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
if (onStopLoadListener == null) {
|
||||
Log.w(TAG, "stopLoadData onStopLoadListener == null >> return;");
|
||||
return;
|
||||
}
|
||||
onStopLoadListener.onStopRefresh();
|
||||
if (page > HttpManager.PAGE_NUM_0) {
|
||||
onStopLoadListener.onStopLoadMore(isHaveMore);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean isSucceed = false;
|
||||
/**处理列表
|
||||
* @param page
|
||||
* @param newList 新数据列表
|
||||
* @param isCache
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
public synchronized void handleList(int page, List<T> newList, boolean isCache) {
|
||||
if (newList == null) {
|
||||
newList = new ArrayList<T>();
|
||||
}
|
||||
isSucceed = ! newList.isEmpty();
|
||||
Log.i(TAG, "\n\n<<<<<<<<<<<<<<<<<\n handleList newList.size = " + newList.size() + "; isCache = " + isCache
|
||||
+ "; page = " + page + "; isSucceed = " + isSucceed);
|
||||
|
||||
if (page <= HttpManager.PAGE_NUM_0) {
|
||||
Log.i(TAG, "handleList page <= HttpManager.PAGE_NUM_0 >>>> ");
|
||||
saveCacheStart = 0;
|
||||
list = new ArrayList<T>(newList);
|
||||
if (isCache == false && list.isEmpty() == false) {
|
||||
Log.i(TAG, "handleList isCache == false && list.isEmpty() == false >> isToLoadCache = false;");
|
||||
isToLoadCache = false;
|
||||
}
|
||||
} else {
|
||||
Log.i(TAG, "handleList page > HttpManager.PAGE_NUM_0 >>>> ");
|
||||
if (list == null) {
|
||||
list = new ArrayList<T>();
|
||||
}
|
||||
saveCacheStart = list.size();
|
||||
isHaveMore = ! newList.isEmpty();
|
||||
if (isHaveMore) {
|
||||
list.addAll(newList);
|
||||
}
|
||||
}
|
||||
|
||||
Log.i(TAG, "handleList list.size = " + list.size() + "; isHaveMore = " + isHaveMore
|
||||
+ "; isToLoadCache = " + isToLoadCache + "; saveCacheStart = " + saveCacheStart
|
||||
+ "\n>>>>>>>>>>>>>>>>>>\n\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**加载成功
|
||||
* isCache = false;
|
||||
* @param page
|
||||
* @param newList
|
||||
*/
|
||||
public synchronized void onLoadSucceed(final int page, final List<T> newList) {
|
||||
onLoadSucceed(page, newList, false);
|
||||
}
|
||||
/**加载成功
|
||||
* @param page
|
||||
* @param newList
|
||||
* @param isCache newList是否为缓存
|
||||
*/
|
||||
private synchronized void onLoadSucceed(final int page, final List<T> newList, final boolean isCache) {
|
||||
runThread(TAG + "onLoadSucceed", new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(TAG, "onLoadSucceed page = " + page + "; isCache = " + isCache + " >> handleList...");
|
||||
handleList(page, newList, isCache);
|
||||
|
||||
runUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
stopLoadData(page, isCache);
|
||||
setList(list);
|
||||
}
|
||||
});
|
||||
|
||||
if (isToSaveCache && isCache == false) {
|
||||
saveCache(newList);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**加载失败
|
||||
* @param page
|
||||
* @param e
|
||||
*/
|
||||
public synchronized void onLoadFailed(int page, Exception e) {
|
||||
Log.e(TAG, "onLoadFailed page = " + page + "; e = " + (e == null ? null : e.getMessage()));
|
||||
stopLoadData(page);
|
||||
showShortToast(R.string.get_failed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//缓存<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
// /**
|
||||
// * 获取缓存每页数量
|
||||
// * @return > 0 ?缓存 : 不缓存
|
||||
// */
|
||||
// public int getCacheCount() {
|
||||
// //让给服务器返回每页数量为count的数据,不行的话在子类重写 Math.max(10, newList == null ? 0 : newList.size());
|
||||
// return CacheManager.MAX_PAGE_SIZE;
|
||||
// }
|
||||
|
||||
private int saveCacheStart;
|
||||
/**保存缓存
|
||||
* @param newList
|
||||
*/
|
||||
public synchronized void saveCache(List<T> newList) {
|
||||
if (cacheCallBack == null || newList == null || newList.isEmpty()) {
|
||||
Log.e(TAG, "saveCache cacheCallBack == null || newList == null || newList.isEmpty() >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
LinkedHashMap<String, T> map = new LinkedHashMap<String, T>();
|
||||
for (T data : newList) {
|
||||
if (data != null) {
|
||||
map.put(cacheCallBack.getCacheId(data), data);//map.put(null, data);不会崩溃
|
||||
}
|
||||
}
|
||||
|
||||
CacheManager.getInstance().saveList(cacheCallBack.getCacheClass(), cacheCallBack.getCacheGroup()
|
||||
, map, saveCacheStart, cacheCallBack.getCacheCount());
|
||||
}
|
||||
//缓存>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**刷新(从头加载)
|
||||
* @must 在子类onCreate中调用,建议放在最后
|
||||
*/
|
||||
public void onRefresh() {
|
||||
loadData(HttpManager.PAGE_NUM_0);
|
||||
}
|
||||
/**加载更多
|
||||
*/
|
||||
public void onLoadMore() {
|
||||
if (isSucceed == false && page <= HttpManager.PAGE_NUM_0) {
|
||||
Log.w(TAG, "onLoadMore isSucceed == false && page <= HttpManager.PAGE_NUM_0 >> return;");
|
||||
return;
|
||||
}
|
||||
loadData(page + (isSucceed ? 1 : 0));
|
||||
}
|
||||
|
||||
|
||||
// 系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
// 类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
isLoading = false;
|
||||
isHaveMore = false;
|
||||
isToSaveCache = false;
|
||||
isToLoadCache = false;
|
||||
|
||||
super.onDestroy();
|
||||
|
||||
lvBaseList = null;
|
||||
list = null;
|
||||
|
||||
onStopLoadListener = null;
|
||||
cacheCallBack = null;
|
||||
}
|
||||
|
||||
// 类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
// 系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// 内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
// 内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**基础Model,继承它可以省去部分代码,也可以不继承
|
||||
* *isCorrect可以用于BaseModel子类的数据校验
|
||||
* *implements Serializable 是为了网络传输字节流转换
|
||||
* @author Lemon
|
||||
* @use extends BaseModel
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class BaseModel implements Serializable {
|
||||
|
||||
public long id;
|
||||
|
||||
//对子类不起作用
|
||||
// /**默认构造方法,JSON等解析时必须要有
|
||||
// */
|
||||
// public BaseModel() {
|
||||
// }
|
||||
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
/**数据正确性校验
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static boolean isCorrect(BaseModel data) {
|
||||
return data != null && data.isCorrect();
|
||||
}
|
||||
|
||||
/**数据正确性校验
|
||||
* @return
|
||||
*/
|
||||
protected abstract boolean isCorrect();//public导致JSON.toJSONString会添加correct字段
|
||||
|
||||
}
|
@ -1,496 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.interfaces.OnBottomDragListener;
|
||||
import zuo.biao.library.interfaces.ViewPresenter;
|
||||
import zuo.biao.library.ui.TopTabView;
|
||||
import zuo.biao.library.ui.TopTabView.OnTabSelectedListener;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**基础带标签的FragmentActivity
|
||||
* @author Lemon
|
||||
* @see #onCreate
|
||||
* @see #setContentView
|
||||
* @use extends BaseTabActivity, 具体参考.DemoTabActivity
|
||||
* @must 在子类onCreate中调用initView();initData();initEvent();
|
||||
*/
|
||||
public abstract class BaseTabActivity extends BaseActivity implements ViewPresenter
|
||||
, OnClickListener, OnTabSelectedListener {
|
||||
private static final String TAG = "BaseTabActivity";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param savedInstanceState
|
||||
* @return
|
||||
* @must 1.不要在子类重复这个类中onCreate中的代码;
|
||||
* 2.在子类onCreate中super.onCreate(savedInstanceState);
|
||||
* initView();initData();initEvent();
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
onCreate(savedInstanceState, 0);
|
||||
}
|
||||
/**
|
||||
* @param savedInstanceState
|
||||
* @param layoutResID activity全局视图view的布局资源id,默认值为R.layout.base_tab_activity
|
||||
* @return
|
||||
* @must 1.不要在子类重复这个类中onCreate中的代码;
|
||||
* 2.在子类onCreate中super.onCreate(savedInstanceState, layoutResID);
|
||||
* initView();initData();initEvent();
|
||||
*/
|
||||
protected final void onCreate(Bundle savedInstanceState, int layoutResID) {
|
||||
onCreate(savedInstanceState, layoutResID, null);
|
||||
}
|
||||
/**
|
||||
* @param savedInstanceState
|
||||
* @param listener this - 滑动返回 ; null - 没有滑动返回
|
||||
* @return
|
||||
* @must 1.不要在子类重复这个类中onCreate中的代码;
|
||||
* 2.在子类onCreate中super.onCreate(savedInstanceState, listener);
|
||||
* initView();initData();initEvent();
|
||||
*/
|
||||
protected final void onCreate(Bundle savedInstanceState, OnBottomDragListener listener) {
|
||||
onCreate(savedInstanceState, 0, listener);
|
||||
}
|
||||
/**
|
||||
* @param savedInstanceState
|
||||
* @param layoutResID activity全局视图view的布局资源id。 <= 0 ? R.layout.base_tab_activity : layoutResID
|
||||
* @param listener == null ? 没有滑动返回 : 滑动返回
|
||||
* @return
|
||||
* @must 1.不要在子类重复这个类中onCreate中的代码;
|
||||
* 2.在子类onCreate中super.onCreate(savedInstanceState, layoutResID, listener);
|
||||
* initView();initData();initEvent();
|
||||
*/
|
||||
protected final void onCreate(Bundle savedInstanceState, int layoutResID, OnBottomDragListener listener) {
|
||||
super.onCreate(savedInstanceState);
|
||||
super.setContentView(layoutResID <= 0 ? R.layout.base_tab_activity : layoutResID, listener);
|
||||
}
|
||||
|
||||
// //BaseActivity重写setContentView后这个方法一定会被调用,final有无都会导致崩溃,去掉throw Exception也会导致contentView为null而崩溃
|
||||
// //防止子类中setContentView <<<<<<<<<<<<<<<<<<<<<<<<
|
||||
// /**
|
||||
// * @warn 不支持setContentView,传界面布局请使用onCreate(Bundle savedInstanceState, int layoutResID)等方法
|
||||
// */
|
||||
// @Override
|
||||
// public final void setContentView(int layoutResID) {
|
||||
// setContentView(null);
|
||||
// }
|
||||
// /**
|
||||
// * @warn 不支持setContentView,传界面布局请使用onCreate(Bundle savedInstanceState, int layoutResID)等方法
|
||||
// */
|
||||
// @Override
|
||||
// public final void setContentView(View view) {
|
||||
// setContentView(null, null);
|
||||
// }
|
||||
// /**
|
||||
// * @warn 不支持setContentView,传界面布局请使用onCreate(Bundle savedInstanceState, int layoutResID)等方法
|
||||
// */
|
||||
// @Override
|
||||
// public final void setContentView(View view, LayoutParams params) {
|
||||
// throw new UnsupportedOperationException(TAG + "不支持setContentView" +
|
||||
// ",传界面布局请使用onCreate(Bundle savedInstanceState, int layoutResID)等方法");
|
||||
// }
|
||||
// //防止子类中setContentView >>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
@Nullable
|
||||
private TextView tvBaseTabTitle;
|
||||
|
||||
@Nullable
|
||||
private View ivBaseTabReturn;
|
||||
@Nullable
|
||||
private TextView tvBaseTabReturn;
|
||||
@Nullable
|
||||
private TextView tvBaseTabForward;
|
||||
|
||||
@Nullable
|
||||
private ViewGroup llBaseTabTopRightButtonContainer;
|
||||
|
||||
private ViewGroup llBaseTabTabContainer;
|
||||
/**
|
||||
* 如果在子类中调用(即super.initView());则view必须含有initView中初始化用到的id(非@Nullable标记)且id对应的View的类型全部相同;
|
||||
* 否则必须在子类initView中重写这个类中initView内的代码(所有id替换成可用id)
|
||||
*/
|
||||
@Override
|
||||
public void initView() {// 必须调用
|
||||
|
||||
tvBaseTabTitle = (TextView) findViewById(R.id.tvBaseTabTitle);
|
||||
|
||||
ivBaseTabReturn = findViewById(R.id.ivBaseTabReturn);
|
||||
tvBaseTabReturn = (TextView) findViewById(R.id.tvBaseTabReturn);
|
||||
|
||||
llBaseTabTopRightButtonContainer = (ViewGroup)
|
||||
findViewById(R.id.llBaseTabTopRightButtonContainer);
|
||||
|
||||
llBaseTabTabContainer = (ViewGroup) findViewById(R.id.llBaseTabTabContainer);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* == true >> 每次点击相应tab都加载,调用getFragment方法重新对点击的tab对应的fragment赋值。
|
||||
* 如果不希望重载,可以setOnTabSelectedListener,然后在onTabSelected内重写点击tab事件。
|
||||
*/
|
||||
protected boolean needReload = false;
|
||||
/**
|
||||
* 当前显示的tab所在位置,对应fragment所在位置
|
||||
*/
|
||||
protected int currentPosition = 0;
|
||||
|
||||
/**选择下一个tab和fragment
|
||||
*/
|
||||
public void selectNext() {
|
||||
select((getCurrentPosition() + 1) % getCount());
|
||||
}
|
||||
/**选择tab和fragment
|
||||
* @param position
|
||||
*/
|
||||
public void select(int position) {
|
||||
topTabView.select(position);
|
||||
}
|
||||
|
||||
/**选择并显示fragment
|
||||
* @param position
|
||||
*/
|
||||
public void selectFragment(int position) {
|
||||
if (fragments == null || fragments.length != getCount()) {
|
||||
if (fragments != null) {
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
for (int i = 0; i < fragments.length; i++) {
|
||||
fragmentTransaction.remove(fragments[i]);
|
||||
}
|
||||
fragmentTransaction.commit();
|
||||
}
|
||||
|
||||
fragments = new Fragment[getCount()];
|
||||
}
|
||||
|
||||
if (currentPosition == position) {
|
||||
if (needReload == false && fragments[position] != null && fragments[position].isVisible()) {
|
||||
Log.w(TAG, "selectFragment currentPosition == position" +
|
||||
" >> fragments[position] != null && fragments[position].isVisible()" +
|
||||
" >> return; ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (needReload || fragments[position] == null) {
|
||||
fragments[position] = getFragment(position);
|
||||
}
|
||||
|
||||
//全局的fragmentTransaction因为already committed 崩溃
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
fragmentTransaction.hide(fragments[currentPosition]);
|
||||
if (fragments[position].isAdded() == false) {
|
||||
fragmentTransaction.add(R.id.flBaseTabFragmentContainer, fragments[position]);
|
||||
}
|
||||
fragmentTransaction.show(fragments[position]).commit();
|
||||
|
||||
this.currentPosition = position;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
protected TopTabView topTabView;
|
||||
private Fragment[] fragments;
|
||||
@Override
|
||||
public void initData() {// 必须调用
|
||||
|
||||
if (tvBaseTabTitle != null) {
|
||||
tvBaseTabTitle.setVisibility(StringUtil.isNotEmpty(getTitleName(), true) ? View.VISIBLE : View.GONE);
|
||||
tvBaseTabTitle.setText(StringUtil.getTrimedString(getTitleName()));
|
||||
}
|
||||
|
||||
//返回按钮<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
String returnName = getReturnName();
|
||||
|
||||
if (returnName == null) {
|
||||
if (ivBaseTabReturn != null) {
|
||||
ivBaseTabReturn.setVisibility(View.GONE);
|
||||
}
|
||||
if (tvBaseTabReturn != null) {
|
||||
tvBaseTabReturn.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
boolean isReturnButtonHasName = StringUtil.isNotEmpty(returnName, true);
|
||||
if (ivBaseTabReturn != null) {
|
||||
ivBaseTabReturn.setVisibility(isReturnButtonHasName ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
if (tvBaseTabReturn != null) {
|
||||
tvBaseTabReturn.setVisibility(isReturnButtonHasName ? View.VISIBLE : View.GONE);
|
||||
tvBaseTabReturn.setText(StringUtil.getTrimedString(returnName));
|
||||
}
|
||||
}
|
||||
//返回按钮>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//前进按钮<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
String forwardName = getForwardName();
|
||||
if (StringUtil.isNotEmpty(forwardName, true)) {
|
||||
tvBaseTabForward = addTopRightButton(newTopRightTextView(context, StringUtil.getTrimedString(forwardName)));
|
||||
}
|
||||
|
||||
if (llBaseTabTopRightButtonContainer != null
|
||||
&& topRightButtonList != null && topRightButtonList.size() > 0) {
|
||||
|
||||
llBaseTabTopRightButtonContainer.removeAllViews();
|
||||
for (View btn : topRightButtonList) {
|
||||
llBaseTabTopRightButtonContainer.addView(btn);
|
||||
}
|
||||
}
|
||||
//前进按钮>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//tab<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
topTabView = new TopTabView(context, getResources());
|
||||
llBaseTabTabContainer.removeAllViews();
|
||||
llBaseTabTabContainer.addView(topTabView.createView(getLayoutInflater()));
|
||||
topTabView.setCurrentPosition(currentPosition);
|
||||
topTabView.bindView(getTabNames());
|
||||
//tab>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
// fragmentActivity子界面初始化<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
selectFragment(currentPosition);
|
||||
|
||||
// fragmentActivity子界面初始化>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
||||
|
||||
/**获取导航栏标题名
|
||||
* @return null - View.GONE; "" - <; "xxx" - "xxx"
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public abstract String getTitleName();
|
||||
|
||||
/**获取导航栏标题名
|
||||
* @return null - View.GONE; "" - <; "xxx" - "xxx"
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public abstract String getReturnName();
|
||||
|
||||
//top right button <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**获取导航栏标题名
|
||||
* @return null - View.GONE; "" - View.GONE; "xxx" - "xxx"
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public abstract String getForwardName();
|
||||
|
||||
@Nullable
|
||||
private List<View> topRightButtonList = new ArrayList<View>();
|
||||
/**添加右上方导航栏按钮
|
||||
* @warn 在initData前使用才有效
|
||||
* @param topRightButton 不会在这个类设置监听,需要自行设置
|
||||
*/
|
||||
public <V extends View> V addTopRightButton(V topRightButton) {
|
||||
if (topRightButton != null) {
|
||||
topRightButtonList.add(topRightButton);
|
||||
}
|
||||
return topRightButton;
|
||||
}
|
||||
/**新建右上方导航栏按钮
|
||||
* @param context
|
||||
* @param drawable
|
||||
* @return
|
||||
*/
|
||||
public ImageView newTopRightImageView(Context context, int drawable) {
|
||||
return newTopRightImageView(context, getResources().getDrawable(drawable));
|
||||
}
|
||||
/**新建右上方导航栏按钮
|
||||
* @param context
|
||||
* @param drawable
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint({ "NewApi", "InflateParams" })
|
||||
public ImageView newTopRightImageView(Context context, Drawable drawable) {
|
||||
ImageView topRightButton = (ImageView) LayoutInflater.from(context).inflate(R.layout.top_right_iv, null);
|
||||
topRightButton.setImageDrawable(drawable);
|
||||
return topRightButton;
|
||||
}
|
||||
/**新建右上方导航栏按钮
|
||||
* @param context
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint({ "NewApi", "InflateParams" })
|
||||
public TextView newTopRightTextView(Context context, String name) {
|
||||
TextView topRightButton = (TextView) LayoutInflater.from(context).inflate(R.layout.top_right_tv, null);
|
||||
topRightButton.setText(name);
|
||||
return topRightButton;
|
||||
}
|
||||
|
||||
//top right button >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
/**获取标签名称数组
|
||||
* @return
|
||||
*/
|
||||
protected abstract String[] getTabNames();
|
||||
|
||||
/**获取新的Fragment
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
protected abstract Fragment getFragment(int position);
|
||||
|
||||
|
||||
/**获取Tab(或Fragment)的数量
|
||||
* @return
|
||||
*/
|
||||
public int getCount() {
|
||||
return topTabView == null ? 0 : topTabView.getCount();
|
||||
}
|
||||
|
||||
/**获取当前Tab(或Fragment)的位置
|
||||
* @return
|
||||
*/
|
||||
public int getCurrentPosition() {
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
public TextView getCurrentTab() {
|
||||
return topTabView == null ? null : topTabView.getCurrentTab();
|
||||
};
|
||||
|
||||
public Fragment getCurrentFragment() {
|
||||
return fragments[currentPosition];
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {// 必须调用
|
||||
|
||||
if (ivBaseTabReturn != null) {
|
||||
ivBaseTabReturn.setOnClickListener(this);
|
||||
}
|
||||
if (tvBaseTabReturn != null) {
|
||||
tvBaseTabReturn.setOnClickListener(this);
|
||||
}
|
||||
if (tvBaseTabForward != null) {
|
||||
tvBaseTabForward.setOnClickListener(new OnClickListener() {//没有id
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onForwardClick(v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
topTabView.setOnTabSelectedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabSelected(TextView tvTab, int position, int id) {
|
||||
selectFragment(position);
|
||||
}
|
||||
|
||||
// 系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.getId() == R.id.ivBaseTabReturn || v.getId() == R.id.tvBaseTabReturn) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
topTabView = null;
|
||||
fragments = null;
|
||||
|
||||
ivBaseTabReturn = null;
|
||||
tvBaseTabReturn = null;
|
||||
llBaseTabTopRightButtonContainer = null;
|
||||
llBaseTabTabContainer = null;
|
||||
|
||||
tvBaseTabTitle = null;
|
||||
|
||||
currentPosition = 0;
|
||||
needReload = false;
|
||||
|
||||
topRightButtonList = null;
|
||||
}
|
||||
|
||||
// 类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
// 系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// 内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
// 内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,450 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.interfaces.ViewPresenter;
|
||||
import zuo.biao.library.ui.TopTabView;
|
||||
import zuo.biao.library.ui.TopTabView.OnTabSelectedListener;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**基础带标签的Fragment
|
||||
* @author Lemon
|
||||
* @see #onCreateView
|
||||
* @see #setContentView
|
||||
* @use extends BaseTabFragment, 具体参考.DemoTabFragment
|
||||
* @must 在子类onCreateView中调用initView();initData();initEvent();
|
||||
*/
|
||||
public abstract class BaseTabFragment extends BaseFragment implements ViewPresenter
|
||||
, OnClickListener, OnTabSelectedListener {
|
||||
private static final String TAG = "BaseTabFragment";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* FragmentManager
|
||||
*/
|
||||
protected FragmentManager fragmentManager = null;
|
||||
/**
|
||||
* @warn 如果在子类中super.initView();则view必须含有initView中初始化用到的id且id对应的View的类型全部相同;
|
||||
* 否则必须在子类initView中重写这个类中initView内的代码(所有id替换成可用id)
|
||||
* @param inflater
|
||||
* @param container
|
||||
* @param savedInstanceState
|
||||
* @return
|
||||
* @must 1.不要在子类重复这个类中onCreateView中的代码;
|
||||
* 2.在子类onCreateView中super.onCreateView(inflater, container, savedInstanceState);
|
||||
* initView();initData();initEvent(); return view;
|
||||
*/
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return onCreateView(inflater, container, savedInstanceState, 0);
|
||||
}
|
||||
/**
|
||||
* @param inflater
|
||||
* @param container
|
||||
* @param savedInstanceState
|
||||
* @param layoutResID fragment全局视图view的布局资源id。 <= 0 ? R.layout.base_tab_activity : layoutResID
|
||||
* @return
|
||||
* @must 1.不要在子类重复这个类中onCreateView中的代码;
|
||||
* 2.在子类onCreateView中super.onCreateView(inflater, container, savedInstanceState, layoutResID);
|
||||
* initView();initData();initEvent(); return view;
|
||||
*/
|
||||
public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState
|
||||
, int layoutResID) {
|
||||
//类相关初始化,必须使用<<<<<<<<<<<<<<<<<<
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
//调用这个类的setContentView而崩溃 super.setContentView(layoutResID <= 0 ? R.layout.base_tab_activity : layoutResID);
|
||||
view = inflater.inflate(layoutResID <= 0 ? R.layout.base_tab_activity : layoutResID, container, false);
|
||||
//类相关初始化,必须使用>>>>>>>>>>>>>>>>
|
||||
|
||||
fragmentManager = context.getSupportFragmentManager();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
//防止子类中setContentView <<<<<<<<<<<<<<<<<<<<<<<<
|
||||
/**
|
||||
* @warn 不支持setContentView,传界面布局请使用onCreateView(Bundle savedInstanceState, int layoutResID)等方法
|
||||
*/
|
||||
@Override
|
||||
public void setContentView(int layoutResID) {
|
||||
setContentView(null);
|
||||
}
|
||||
/**
|
||||
* @warn 不支持setContentView,传界面布局请使用onCreateView(Bundle savedInstanceState, int layoutResID)等方法
|
||||
*/
|
||||
@Override
|
||||
public void setContentView(View view) {
|
||||
setContentView(null, null);
|
||||
}
|
||||
/**
|
||||
* @warn 不支持setContentView,传界面布局请使用onCreateView(Bundle savedInstanceState, int layoutResID)等方法
|
||||
*/
|
||||
@Override
|
||||
public void setContentView(View view, LayoutParams params) {
|
||||
throw new UnsupportedOperationException(TAG + "不支持setContentView,传界面布局请使用onCreateView(" +
|
||||
"LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState, int layoutResID)等方法");
|
||||
}
|
||||
//防止子类中setContentView >>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
@Nullable
|
||||
private TextView tvBaseTabTitle;
|
||||
|
||||
@Nullable
|
||||
private View ivBaseTabReturn;
|
||||
@Nullable
|
||||
private TextView tvBaseTabReturn;
|
||||
|
||||
@Nullable
|
||||
private ViewGroup llBaseTabTopRightButtonContainer;
|
||||
|
||||
private ViewGroup llBaseTabTabContainer;
|
||||
/**
|
||||
* 如果在子类中调用(即super.initView());则view必须含有initView中初始化用到的id(非@Nullable标记)且id对应的View的类型全部相同;
|
||||
* 否则必须在子类initView中重写这个类中initView内的代码(所有id替换成可用id)
|
||||
*/
|
||||
@Override
|
||||
public void initView() {// 必须调用
|
||||
|
||||
tvBaseTabTitle = (TextView) findViewById(R.id.tvBaseTabTitle);
|
||||
|
||||
ivBaseTabReturn = findViewById(R.id.ivBaseTabReturn);
|
||||
tvBaseTabReturn = (TextView) findViewById(R.id.tvBaseTabReturn);
|
||||
|
||||
llBaseTabTopRightButtonContainer = (ViewGroup)
|
||||
findViewById(R.id.llBaseTabTopRightButtonContainer);
|
||||
|
||||
llBaseTabTabContainer = (ViewGroup) findViewById(R.id.llBaseTabTabContainer);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* == true >> 每次点击相应tab都加载,调用getFragment方法重新对点击的tab对应的fragment赋值。
|
||||
* 如果不希望重载,可以setOnTabSelectedListener,然后在onTabSelected内重写点击tab事件。
|
||||
*/
|
||||
protected boolean needReload = false;
|
||||
/**
|
||||
* 当前显示的tab所在位置,对应fragment所在位置
|
||||
*/
|
||||
protected int currentPosition = 0;
|
||||
|
||||
/**选择下一个tab和fragment
|
||||
*/
|
||||
public void selectNext() {
|
||||
select((getCurrentPosition() + 1) % getCount());
|
||||
}
|
||||
/**选择tab和fragment
|
||||
* @param position
|
||||
*/
|
||||
public void select(int position) {
|
||||
topTabView.select(position);
|
||||
}
|
||||
|
||||
/**选择并显示fragment
|
||||
* @param position
|
||||
*/
|
||||
public void selectFragment(int position) {
|
||||
if (currentPosition == position) {
|
||||
if (needReload == false && fragments[position] != null && fragments[position].isVisible()) {
|
||||
Log.w(TAG, "selectFragment currentPosition == position" +
|
||||
" >> fragments[position] != null && fragments[position].isVisible()" +
|
||||
" >> return; ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (needReload || fragments[position] == null) {
|
||||
fragments[position] = getFragment(position);
|
||||
}
|
||||
|
||||
//全局的fragmentTransaction因为already committed 崩溃
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
fragmentTransaction.hide(fragments[currentPosition]);
|
||||
if (fragments[position].isAdded() == false) {
|
||||
fragmentTransaction.add(R.id.flBaseTabFragmentContainer, fragments[position]);
|
||||
}
|
||||
fragmentTransaction.show(fragments[position]).commit();
|
||||
|
||||
this.currentPosition = position;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private String topReturnButtonName;
|
||||
|
||||
protected TopTabView topTabView;
|
||||
private Fragment[] fragments;
|
||||
@Override
|
||||
public void initData() {// 必须调用
|
||||
|
||||
if (tvBaseTabTitle != null) {
|
||||
tvBaseTabTitle.setVisibility(StringUtil.isNotEmpty(getTitleName(), true) ? View.VISIBLE : View.GONE);
|
||||
tvBaseTabTitle.setText(StringUtil.getTrimedString(getTitleName()));
|
||||
}
|
||||
|
||||
topReturnButtonName = getReturnName();
|
||||
|
||||
if (topReturnButtonName == null) {
|
||||
if (ivBaseTabReturn != null) {
|
||||
ivBaseTabReturn.setVisibility(View.GONE);
|
||||
}
|
||||
if (tvBaseTabReturn != null) {
|
||||
tvBaseTabReturn.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
boolean isReturnButtonHasName = StringUtil.isNotEmpty(topReturnButtonName, true);
|
||||
if (ivBaseTabReturn != null) {
|
||||
ivBaseTabReturn.setVisibility(isReturnButtonHasName ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
if (tvBaseTabReturn != null) {
|
||||
tvBaseTabReturn.setVisibility(isReturnButtonHasName ? View.VISIBLE : View.GONE);
|
||||
tvBaseTabReturn.setText(StringUtil.getTrimedString(topReturnButtonName));
|
||||
}
|
||||
}
|
||||
|
||||
if (llBaseTabTopRightButtonContainer != null
|
||||
&& topRightButtonList != null && topRightButtonList.size() > 0) {
|
||||
|
||||
llBaseTabTopRightButtonContainer.removeAllViews();
|
||||
for (View btn : topRightButtonList) {
|
||||
llBaseTabTopRightButtonContainer.addView(btn);
|
||||
}
|
||||
}
|
||||
|
||||
topTabView = new TopTabView(context, getResources());
|
||||
llBaseTabTabContainer.removeAllViews();
|
||||
llBaseTabTabContainer.addView(topTabView.createView(context.getLayoutInflater()));
|
||||
topTabView.setCurrentPosition(currentPosition);
|
||||
topTabView.bindView(getTabNames());
|
||||
|
||||
|
||||
// fragmentActivity子界面初始化<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
fragments = new Fragment[getCount()];
|
||||
selectFragment(currentPosition);
|
||||
|
||||
// fragmentActivity子界面初始化>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//top right button <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public final String getForwardName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private List<View> topRightButtonList = new ArrayList<View>();
|
||||
/**添加右上方导航栏按钮
|
||||
* @warn 在initData前使用才有效
|
||||
* @param topRightButton 不会在这个类设置监听,需要自行设置
|
||||
*/
|
||||
public <V extends View> V addTopRightButton(V topRightButton) {
|
||||
if (topRightButton != null) {
|
||||
topRightButtonList.add(topRightButton);
|
||||
}
|
||||
return topRightButton;
|
||||
}
|
||||
/**新建右上方导航栏按钮
|
||||
* @param context
|
||||
* @param drawable
|
||||
* @return
|
||||
*/
|
||||
public ImageView newTopRightImageView(Context context, int drawable) {
|
||||
return newTopRightImageView(context, getResources().getDrawable(drawable));
|
||||
}
|
||||
/**新建右上方导航栏按钮
|
||||
* @param context
|
||||
* @param drawable
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint({ "NewApi", "InflateParams" })
|
||||
public ImageView newTopRightImageView(Context context, Drawable drawable) {
|
||||
ImageView topRightButton = (ImageView) LayoutInflater.from(context).inflate(R.layout.top_right_iv, null);
|
||||
topRightButton.setImageDrawable(drawable);
|
||||
return topRightButton;
|
||||
}
|
||||
/**新建右上方导航栏按钮
|
||||
* @param context
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint({ "NewApi", "InflateParams" })
|
||||
public TextView newTopRightTextView(Context context, String name) {
|
||||
TextView topRightButton = (TextView) LayoutInflater.from(context).inflate(R.layout.top_right_tv, null);
|
||||
topRightButton.setText(name);
|
||||
return topRightButton;
|
||||
}
|
||||
|
||||
//top right button >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
/**获取标签名称数组
|
||||
* @return
|
||||
*/
|
||||
protected abstract String[] getTabNames();
|
||||
|
||||
/**获取新的Fragment
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
protected abstract Fragment getFragment(int position);
|
||||
|
||||
|
||||
/**获取Tab(或Fragment)的数量
|
||||
* @return
|
||||
*/
|
||||
public int getCount() {
|
||||
return topTabView == null ? 0 : topTabView.getCount();
|
||||
}
|
||||
|
||||
/**获取当前Tab(或Fragment)的位置
|
||||
* @return
|
||||
*/
|
||||
public int getCurrentPosition() {
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
public TextView getCurrentTab() {
|
||||
return topTabView == null ? null : topTabView.getCurrentTab();
|
||||
};
|
||||
|
||||
public Fragment getCurrentFragment() {
|
||||
return fragments[currentPosition];
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {// 必须调用
|
||||
|
||||
if (ivBaseTabReturn != null) {
|
||||
ivBaseTabReturn.setOnClickListener(this);
|
||||
}
|
||||
if (tvBaseTabReturn != null) {
|
||||
tvBaseTabReturn.setOnClickListener(this);
|
||||
}
|
||||
|
||||
topTabView.setOnTabSelectedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabSelected(TextView tvTab, int position, int id) {
|
||||
selectFragment(position);
|
||||
}
|
||||
|
||||
// 系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.getId() == R.id.ivBaseTabReturn || v.getId() == R.id.tvBaseTabReturn) {
|
||||
context.finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
topTabView = null;
|
||||
fragments = null;
|
||||
|
||||
ivBaseTabReturn = null;
|
||||
tvBaseTabReturn = null;
|
||||
llBaseTabTopRightButtonContainer = null;
|
||||
llBaseTabTabContainer = null;
|
||||
|
||||
tvBaseTabTitle = null;
|
||||
topReturnButtonName = null;
|
||||
|
||||
currentPosition = 0;
|
||||
needReload = false;
|
||||
|
||||
topRightButtonList = null;
|
||||
}
|
||||
|
||||
// 类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
// 系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// 内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
// 内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,357 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.util.CommonUtil;
|
||||
import zuo.biao.library.util.Log;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.View.OnTouchListener;
|
||||
|
||||
/**基础自定义View
|
||||
* @author Lemon
|
||||
* @param <T> 数据模型(model/JavaBean)类
|
||||
* @see OnViewClickListener
|
||||
* @see #onDestroy
|
||||
* @use extends BaseView<T>, 具体参考.DemoView
|
||||
*/
|
||||
public abstract class BaseView<T> {
|
||||
private static final String TAG = "BaseView";
|
||||
|
||||
/**
|
||||
* 传入的Activity,可在子类直接使用
|
||||
*/
|
||||
public Activity context;
|
||||
public Resources resources;
|
||||
public BaseView(Activity context, Resources resources) {
|
||||
this.context = context;
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
/**点击View的事件监听回调,主要是为了activity或fragment间接通过adapter接管baseView的点击事件
|
||||
* @param <T>
|
||||
* @param <BV>
|
||||
* @must 子类重写setOnClickListener方法且view.setOnClickListener(listener)事件统一写在这个方法里面
|
||||
*/
|
||||
public interface OnViewClickListener<T, BV extends BaseView<T>> {
|
||||
/**onClick(v)事件由这个方法接管
|
||||
* @param v
|
||||
* @param bv
|
||||
*/
|
||||
void onViewClick(View v, BV bv);
|
||||
}
|
||||
|
||||
/**数据改变回调接口
|
||||
* (Object) getData() - 改变的数据
|
||||
*/
|
||||
public interface OnDataChangedListener {
|
||||
void onDataChanged();
|
||||
}
|
||||
|
||||
public OnDataChangedListener onDataChangedListener;//数据改变回调监听回调的实例
|
||||
/**设置数据改变事件监听回调
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnDataChangedListener(OnDataChangedListener listener) {
|
||||
onDataChangedListener = listener;
|
||||
}
|
||||
|
||||
public OnTouchListener onTouchListener;//接触View回调监听回调的实例
|
||||
/**设置接触View事件监听回调
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnTouchListener(OnTouchListener listener) {
|
||||
onTouchListener = listener;
|
||||
}
|
||||
|
||||
public OnClickListener onClickListener;//点击View回调监听回调的实例
|
||||
/**设置点击View事件监听回调
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnClickListener(OnClickListener listener) {
|
||||
onClickListener = listener;
|
||||
if (onClickViewList != null) {
|
||||
for (View v : onClickViewList) {
|
||||
if (v != null) {
|
||||
v.setOnClickListener(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OnLongClickListener onLongClickListener;//长按View回调监听回调的实例
|
||||
/**设置长按View事件监听回调
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnLongClickListener(OnLongClickListener listener) {
|
||||
onLongClickListener = listener;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 子类整个视图,可在子类直接使用
|
||||
* @must createView方法内对其赋值且不能为null
|
||||
*/
|
||||
protected View convertView = null;
|
||||
|
||||
protected List<View> onClickViewList;
|
||||
/**通过id查找并获取控件,使用时不需要强转
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <V extends View> V findViewById(int id) {
|
||||
return (V) convertView.findViewById(id);
|
||||
}
|
||||
/**通过id查找并获取控件,并setOnClickListener
|
||||
* @param id
|
||||
* @param listener
|
||||
* @return
|
||||
*/
|
||||
public <V extends View> V findViewById(int id, OnClickListener listener) {
|
||||
V v = findViewById(id);
|
||||
v.setOnClickListener(listener);
|
||||
if (onClickViewList == null) {
|
||||
onClickViewList = new ArrayList<View>();
|
||||
}
|
||||
onClickViewList.add(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 视图类型,部分情况下需要根据viewType使用不同layout,对应Adapter的itemViewType
|
||||
*/
|
||||
protected int viewType = 0;
|
||||
/**
|
||||
* data在列表中的位置
|
||||
* @must 只使用bindView(int position, T data)方法来设置position,保证position与data对应正确
|
||||
*/
|
||||
protected int position = 0;
|
||||
/**获取data在列表中的位置
|
||||
*/
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**创建一个新的View
|
||||
* @param inflater - @NonNull,布局解释器
|
||||
* @param viewType - 视图类型,部分情况下需要根据viewType使用不同layout
|
||||
* @return
|
||||
*/
|
||||
public View createView(LayoutInflater inflater, int position, int viewType) {
|
||||
this.position = position;
|
||||
this.viewType = viewType;
|
||||
return createView(inflater);
|
||||
}
|
||||
/**创建一个新的View
|
||||
* @param inflater - @NonNull,布局解释器
|
||||
* @return
|
||||
*/
|
||||
public abstract View createView(LayoutInflater inflater);
|
||||
|
||||
/**获取convertView的宽度
|
||||
* @warn 只能在createView后使用
|
||||
* @return
|
||||
*/
|
||||
public int getWidth() {
|
||||
return convertView.getWidth();
|
||||
}
|
||||
/**获取convertView的高度
|
||||
* @warn 只能在createView后使用
|
||||
* @return
|
||||
*/
|
||||
public int getHeight() {
|
||||
return convertView.getHeight();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected T data = null;
|
||||
/**获取数据
|
||||
* @return
|
||||
*/
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/**设置并显示内容,建议在子类bindView内this.data = data;
|
||||
* @warn 只能在createView后使用
|
||||
* @param data - 传入的数据
|
||||
* @param position - data在列表中的位置
|
||||
* @param viewType - 视图类型,部分情况下需要根据viewType使用不同layout
|
||||
*/
|
||||
public void bindView(T data, int position, int viewType) {
|
||||
this.position = position;
|
||||
this.viewType = viewType;
|
||||
bindView(data);
|
||||
}
|
||||
/**设置并显示内容,建议在子类bindView内this.data = data;
|
||||
* @warn 只能在createView后使用
|
||||
* @param data - 传入的数据
|
||||
*/
|
||||
public abstract void bindView(T data);
|
||||
|
||||
/**获取可见性
|
||||
* @warn 只能在createView后使用
|
||||
* @return 可见性 (View.VISIBLE, View.GONE, View.INVISIBLE);
|
||||
*/
|
||||
public int getVisibility() {
|
||||
return convertView.getVisibility();
|
||||
}
|
||||
/**设置可见性
|
||||
* @warn 只能在createView后使用
|
||||
* @param visibility - 可见性 (View.VISIBLE, View.GONE, View.INVISIBLE);
|
||||
*/
|
||||
public void setVisibility(int visibility) {
|
||||
convertView.setVisibility(visibility);
|
||||
}
|
||||
|
||||
|
||||
/**设置背景
|
||||
* @warn 只能在createView后使用
|
||||
* @param resId
|
||||
*/
|
||||
public void setBackground(int resId) {
|
||||
if (resId > 0 && convertView != null) {
|
||||
try {
|
||||
convertView.setBackgroundResource(resId);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "setBackground try { convertView.setBackgroundResource(resId);" +
|
||||
" \n >> } catch (Exception e) { \n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// /**性能不好
|
||||
// * @param id
|
||||
// * @param s
|
||||
// */
|
||||
// public void setText(int id, String s) {
|
||||
// TextView tv = (TextView) findViewById(id);
|
||||
// tv.setText(s);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
//resources方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
public final Resources getResources() {
|
||||
if(resources == null) {
|
||||
resources = context.getResources();
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
|
||||
public String getString(int id) {
|
||||
return getResources().getString(id);
|
||||
}
|
||||
public int getColor(int id) {
|
||||
return getResources().getColor(id);
|
||||
}
|
||||
public Drawable getDrawable(int id) {
|
||||
return getResources().getDrawable(id);
|
||||
}
|
||||
public float getDimension(int id) {
|
||||
return getResources().getDimension(id);
|
||||
}
|
||||
//resources方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//show short toast 方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
|
||||
* @param stringResId
|
||||
*/
|
||||
public void showShortToast(int stringResId) {
|
||||
CommonUtil.showShortToast(context, stringResId);
|
||||
}
|
||||
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
|
||||
* @param string
|
||||
*/
|
||||
public void showShortToast(String string) {
|
||||
CommonUtil.showShortToast(context, string);
|
||||
}
|
||||
//show short toast 方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//启动新Activity方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**打开新的Activity,向左滑入效果
|
||||
* @param intent
|
||||
*/
|
||||
public void toActivity(final Intent intent) {
|
||||
CommonUtil.toActivity(context, intent);
|
||||
}
|
||||
/**打开新的Activity
|
||||
* @param intent
|
||||
* @param showAnimation
|
||||
*/
|
||||
public void toActivity(final Intent intent, final boolean showAnimation) {
|
||||
CommonUtil.toActivity(context, intent, showAnimation);
|
||||
}
|
||||
/**打开新的Activity,向左滑入效果
|
||||
* @param intent
|
||||
* @param requestCode
|
||||
*/
|
||||
public void toActivity(final Intent intent, final int requestCode) {
|
||||
CommonUtil.toActivity(context, intent, requestCode);
|
||||
}
|
||||
/**打开新的Activity
|
||||
* @param intent
|
||||
* @param requestCode
|
||||
* @param showAnimation
|
||||
*/
|
||||
public void toActivity(final Intent intent, final int requestCode, final boolean showAnimation) {
|
||||
CommonUtil.toActivity(context, intent, requestCode, showAnimation);
|
||||
}
|
||||
//启动新Activity方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
/**销毁并回收内存,建议在对应的View占用大量内存时使用
|
||||
* @warn 只能在UI线程中调用
|
||||
*/
|
||||
public void onDestroy() {
|
||||
if (convertView != null) {
|
||||
try {
|
||||
convertView.destroyDrawingCache();
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "onDestroy try { convertView.destroyDrawingCache();" +
|
||||
" >> } catch (Exception e) {\n" + e.getMessage());
|
||||
}
|
||||
convertView = null;
|
||||
}
|
||||
|
||||
onDataChangedListener = null;
|
||||
onTouchListener = null;
|
||||
onClickListener = null;
|
||||
onLongClickListener = null;
|
||||
onClickViewList = null;
|
||||
|
||||
data = null;
|
||||
position = 0;
|
||||
|
||||
context = null;
|
||||
}
|
||||
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import zuo.biao.library.base.BaseView.OnViewClickListener;
|
||||
import zuo.biao.library.interfaces.AdapterViewPresenter;
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**基础Adapter,使用自定义View
|
||||
* <br> 适用于ListView,GridView等AbsListView的子类
|
||||
* @author Lemon
|
||||
* @param <T> 数据模型(model/JavaBean)类
|
||||
* @param <BV> BaseView的子类
|
||||
* @see #setOnViewClickListener
|
||||
* @use extends BaseViewAdapter<T, BV>, 具体参考 .DemoAdapter3
|
||||
*/
|
||||
public abstract class BaseViewAdapter<T, BV extends BaseView<T>> extends BaseAdapter<T>
|
||||
implements AdapterViewPresenter<T, BV> {
|
||||
// private static final String TAG = "BaseViewAdapter";
|
||||
|
||||
|
||||
public OnViewClickListener<T, BV> onViewClickListener;
|
||||
/**为ItemView设置点击View的事件监听
|
||||
* @param listener
|
||||
* @see BaseView.OnViewClickListener
|
||||
*/
|
||||
public void setOnViewClickListener(OnViewClickListener<T, BV> listener) {
|
||||
onViewClickListener = listener;
|
||||
}
|
||||
|
||||
|
||||
private AdapterViewPresenter<T, BV> presenter;
|
||||
/**在子类构造方法内使用可重写AdapterViewPresenter里的方法
|
||||
* @param presenter
|
||||
*/
|
||||
protected final void setPresenter(AdapterViewPresenter<T, BV> presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
/**
|
||||
* @return presenter == null ? this : presenter;
|
||||
*/
|
||||
protected final AdapterViewPresenter<T, BV> getPresenter() {
|
||||
return presenter == null ? this : presenter;
|
||||
}
|
||||
|
||||
|
||||
public BaseViewAdapter(Activity context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
@SuppressWarnings("unchecked")
|
||||
BV bv = convertView == null ? null : (BV) convertView.getTag();
|
||||
if (bv == null) {
|
||||
bv = getPresenter().createView(position, parent);
|
||||
convertView = bv.createView(inflater, position, getItemViewType(position));
|
||||
setOnClickListener(bv);//比在bindView里调用效率高。像是小众需求,应该去掉直接在子类针对性地实现?
|
||||
|
||||
convertView.setTag(bv);
|
||||
}
|
||||
|
||||
getPresenter().bindView(position, bv);
|
||||
|
||||
return super.getView(position, convertView, parent);
|
||||
}
|
||||
|
||||
/**bv的显示方法
|
||||
* @param position
|
||||
* @param bv
|
||||
*/
|
||||
@Override
|
||||
public void bindView(int position, BV bv) {
|
||||
bv.bindView(getItem(position), position, getItemViewType(position));
|
||||
}
|
||||
|
||||
|
||||
/**设置对ItemView点击事件的处理
|
||||
* @param bv
|
||||
*/
|
||||
protected void setOnClickListener(final BV bv) {
|
||||
if (onViewClickListener != null) {
|
||||
bv.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onViewClickListener.onViewClick(v, bv);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,219 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.base;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.interfaces.ViewPresenter;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**基础带标签的FragmentActivity
|
||||
* @author Lemon
|
||||
* @see #onCreate
|
||||
* @see #setContentView
|
||||
* @use extends BaseViewBottomWindow, 具体参考.DemoTabActivity
|
||||
* @must 在子类onCreate中调用initView();initData();initEvent();
|
||||
*/
|
||||
public abstract class BaseViewBottomWindow<T, BV extends BaseView<T>> extends BaseBottomWindow
|
||||
implements ViewPresenter {
|
||||
// private static final String TAG = "BaseViewBottomWindow";
|
||||
|
||||
|
||||
/**
|
||||
* @param savedInstanceState
|
||||
* @return
|
||||
* @must 1.不要在子类重复这个类中onCreate中的代码;
|
||||
* 2.在子类onCreate中super.onCreate(savedInstanceState);
|
||||
* initView();initData();initEvent();
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
onCreate(savedInstanceState, 0);
|
||||
}
|
||||
/**
|
||||
* @param savedInstanceState
|
||||
* @param layoutResID activity全局视图view的布局资源id。 <= 0 ? R.layout.base_view_bottom_window : layoutResID
|
||||
* @return
|
||||
* @must 1.不要在子类重复这个类中onCreate中的代码;
|
||||
* 2.在子类onCreate中super.onCreate(savedInstanceState, layoutResID, listener);
|
||||
* initView();initData();initEvent();
|
||||
*/
|
||||
protected final void onCreate(Bundle savedInstanceState, int layoutResID) {
|
||||
super.onCreate(savedInstanceState);
|
||||
super.setContentView(layoutResID <= 0 ? R.layout.base_view_bottom_window : layoutResID);
|
||||
}
|
||||
|
||||
// //重写setContentView后这个方法一定会被调用,final有无都会导致崩溃,去掉throw Exception也会导致contentView为null而崩溃
|
||||
// //防止子类中setContentView <<<<<<<<<<<<<<<<<<<<<<<<
|
||||
// /**
|
||||
// * @warn 不支持setContentView,传界面布局请使用onCreate(Bundle savedInstanceState, int layoutResID)等方法
|
||||
// */
|
||||
// @Override
|
||||
// public final void setContentView(int layoutResID) {
|
||||
// setContentView(null);
|
||||
// }
|
||||
// /**
|
||||
// * @warn 不支持setContentView,传界面布局请使用onCreate(Bundle savedInstanceState, int layoutResID)等方法
|
||||
// */
|
||||
// @Override
|
||||
// public final void setContentView(View view) {
|
||||
// setContentView(null, null);
|
||||
// }
|
||||
// /**
|
||||
// * @warn 不支持setContentView,传界面布局请使用onCreate(Bundle savedInstanceState, int layoutResID)等方法
|
||||
// */
|
||||
// @Override
|
||||
// public final void setContentView(View view, LayoutParams params) {
|
||||
// throw new UnsupportedOperationException(TAG + "不支持setContentView" +
|
||||
// ",传界面布局请使用onCreate(Bundle savedInstanceState, int layoutResID)等方法");
|
||||
// }
|
||||
// //防止子类中setContentView >>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
protected ViewGroup llBaseViewBottomWindowContainer;
|
||||
|
||||
@Nullable
|
||||
protected TextView tvBaseViewBottomWindowReturn;
|
||||
@Nullable
|
||||
protected TextView tvBaseViewBottomWindowForward;
|
||||
/**
|
||||
* 如果在子类中调用(即super.initView());则view必须含有initView中初始化用到的id(非@Nullable标记)且id对应的View的类型全部相同;
|
||||
* 否则必须在子类initView中重写这个类中initView内的代码(所有id替换成可用id)
|
||||
*/
|
||||
@Override
|
||||
public void initView() {// 必须调用
|
||||
super.initView();
|
||||
autoSetTitle();
|
||||
|
||||
llBaseViewBottomWindowContainer = (ViewGroup) findViewById(R.id.llBaseViewBottomWindowContainer);
|
||||
|
||||
tvBaseViewBottomWindowReturn = (TextView) findViewById(R.id.tvBaseViewBottomWindowReturn);
|
||||
tvBaseViewBottomWindowForward = (TextView) findViewById(R.id.tvBaseViewBottomWindowForward);
|
||||
}
|
||||
|
||||
|
||||
// UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
protected T data;
|
||||
protected BV containerView;
|
||||
@Override
|
||||
public void initData() {// 必须调用
|
||||
super.initData();
|
||||
|
||||
if (tvBaseTitle != null) {
|
||||
String title = getIntent().getStringExtra(INTENT_TITLE);
|
||||
if (StringUtil.isNotEmpty(title, true) == false) {
|
||||
title = getTitleName();
|
||||
}
|
||||
tvBaseTitle.setVisibility(StringUtil.isNotEmpty(title, true) ? View.VISIBLE : View.GONE);
|
||||
tvBaseTitle.setText(StringUtil.getTrimedString(title));
|
||||
}
|
||||
|
||||
if (tvBaseViewBottomWindowReturn != null && StringUtil.isNotEmpty(getReturnName(), true)) {
|
||||
tvBaseViewBottomWindowReturn.setText(StringUtil.getCurrentString());
|
||||
}
|
||||
if (tvBaseViewBottomWindowForward != null && StringUtil.isNotEmpty(getForwardName(), true)) {
|
||||
tvBaseViewBottomWindowForward.setText(StringUtil.getCurrentString());
|
||||
}
|
||||
|
||||
|
||||
llBaseViewBottomWindowContainer.removeAllViews();
|
||||
if (containerView == null) {
|
||||
containerView = createView();
|
||||
llBaseViewBottomWindowContainer.addView(containerView.createView(inflater));
|
||||
}
|
||||
containerView.bindView(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建新的内容View
|
||||
* @return
|
||||
*/
|
||||
protected abstract BV createView();
|
||||
|
||||
// Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {// 必须调用
|
||||
super.initEvent();
|
||||
|
||||
}
|
||||
|
||||
// 系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
// 类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
data = null;
|
||||
llBaseViewBottomWindowContainer.removeAllViews();
|
||||
if (containerView != null) {
|
||||
containerView.onDestroy();
|
||||
}
|
||||
|
||||
super.onDestroy();
|
||||
|
||||
llBaseViewBottomWindowContainer = null;
|
||||
containerView = null;
|
||||
}
|
||||
|
||||
// 类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
// 系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
// Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
// 内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
// 内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
/**
|
||||
* 基础类所在包
|
||||
*/
|
||||
/**
|
||||
* @author Lemon
|
||||
* @use 通用使用方法:extends BaseXX
|
||||
*/
|
||||
package zuo.biao.library.base;
|
@ -1,44 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
|
||||
/**Activity的逻辑接口
|
||||
* @author Lemon
|
||||
* @use implements ActivityPresenter
|
||||
* @warn 对象必须是Activity
|
||||
*/
|
||||
public interface ActivityPresenter extends Presenter {
|
||||
|
||||
/**获取Activity
|
||||
* @must 在非抽象Activity中 return this;
|
||||
*/
|
||||
public Activity getActivity();//无public导致有时自动生成的getActivity方法会缺少public且对此报错
|
||||
|
||||
/**返回按钮被点击
|
||||
* *Activity的返回按钮和底部弹窗的取消按钮几乎是必备,正好原生支持反射;而其它比如Fragment极少用到,也不支持反射
|
||||
* @param v
|
||||
*/
|
||||
public void onReturnClick(View v);
|
||||
|
||||
/**前进按钮被点击
|
||||
* *Activity常用导航栏右边按钮,而且底部弹窗BottomWindow的确定按钮是必备;而其它比如Fragment极少用到,也不支持反射
|
||||
* @param v
|
||||
*/
|
||||
public void onForwardClick(View v);
|
||||
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
/**Adapter使用回调
|
||||
* @author Lemon
|
||||
* @param <A> adapter名称
|
||||
* @see #createAdapter
|
||||
* @see #refreshAdapter
|
||||
* @use implements AdapterCallBack<A>,具体参考.DemoListActivity和.DemoListFragment
|
||||
*/
|
||||
public interface AdapterCallBack<A extends BaseAdapter> {
|
||||
|
||||
/**创建一个Adapter
|
||||
* @return new A();
|
||||
*/
|
||||
A createAdapter();
|
||||
|
||||
/**
|
||||
* BaseAdapter#notifyDataSetChanged()有时无效,有时因列表更新不及时而崩溃,所以需要在自定义adapter内自定义一个刷新方法。
|
||||
* 为什么不直接让自定义Adapter implement OnRefreshListener,从而直接 onRefreshListener.onRefresh(List<T> list) ?
|
||||
* 因为这样的话会不兼容部分 Android SDK 或 第三方库的Adapter
|
||||
*/
|
||||
void refreshAdapter();
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
|
||||
public interface AdapterViewPresenter<T, V> {
|
||||
|
||||
/**生成新的BV
|
||||
* @param position
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
public abstract V createView(int position, ViewGroup parent);
|
||||
|
||||
/**设置BV显示
|
||||
* @param position
|
||||
* @param bv
|
||||
* @return
|
||||
*/
|
||||
public abstract void bindView(int position, V bv);
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
/**缓存回调
|
||||
* @author Lemon
|
||||
* @param <T>
|
||||
* @use 见 .DemoListActivity 和 .UserListFragment
|
||||
*/
|
||||
public interface CacheCallBack<T> {
|
||||
/**
|
||||
* 获取缓存的类,通常是数据模型(model/JavaBean)类
|
||||
* @warn Entry<K, V>这种带类型(这里是K和V)的类不能作为返回值,应该用其它不带类型的类(比如.User)替换
|
||||
* @return null-不缓存
|
||||
*/
|
||||
Class<T> getCacheClass();
|
||||
|
||||
/**
|
||||
* 获取缓存的分组
|
||||
* @return 含非空字符的String ?缓存至对应class的group中 : 至缓存至对应class中
|
||||
*/
|
||||
String getCacheGroup();
|
||||
|
||||
/**
|
||||
* 获取缓存单个数据的id
|
||||
* @param data
|
||||
* @return data == null ? null : "" + data.getId(); //不用long是因为某些数据(例如订单)的id超出long的最大值
|
||||
*/
|
||||
String getCacheId(T data);
|
||||
|
||||
/**
|
||||
* 获取缓存每页数量
|
||||
* @return > 0 ?缓存 : 不缓存
|
||||
*/
|
||||
int getCacheCount();
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
/**Fragment的逻辑接口
|
||||
* @author Lemon
|
||||
* @use implements FragmentPresenter
|
||||
* @warn 对象必须是Fragment
|
||||
*/
|
||||
public interface FragmentPresenter extends Presenter {
|
||||
|
||||
/**
|
||||
* 该Fragment在Activity添加的所有Fragment中的位置
|
||||
*/
|
||||
static final String ARGUMENT_POSITION = "ARGUMENT_POSITION";
|
||||
static final String ARGUMENT_ID = "ARGUMENT_ID";
|
||||
static final String ARGUMENT_USER_ID = "ARGUMENT_USER_ID";
|
||||
|
||||
static final int RESULT_OK = Activity.RESULT_OK;
|
||||
static final int RESULT_CANCELED = Activity.RESULT_CANCELED;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
/**添加回调
|
||||
* @author Lemon
|
||||
* @param <T>
|
||||
*/
|
||||
public interface OnAddListener<T> {
|
||||
|
||||
void onAdd(T object);
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
/**拖拽View底部的回调接口
|
||||
* @author Lemon
|
||||
* @use implements OnBottomDragListener
|
||||
*/
|
||||
public interface OnBottomDragListener {
|
||||
|
||||
/**
|
||||
* @param rightToLeft ?从右向左 : 从左向右
|
||||
*/
|
||||
void onDragBottom(boolean rightToLeft);
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
/**进度回调
|
||||
* @author Lemon
|
||||
* @param <T>
|
||||
*/
|
||||
public interface OnProgressListener {
|
||||
|
||||
void onProgressUpdate(int progress);
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
/**到达(接触到)View的某个边界的监听回调
|
||||
* 一般用于一个(ViewGroup)parent内的(View)child接触到parent的事件监听
|
||||
* @author Lemon
|
||||
* @use implements OnReachViewBorderListener
|
||||
*/
|
||||
public interface OnReachViewBorderListener {
|
||||
static final int TYPE_TOP = 0;
|
||||
static final int TYPE_BOTTOM = 1;
|
||||
static final int TYPE_LEFT = 2;
|
||||
static final int TYPE_RIGHT = 3;
|
||||
|
||||
/**到达(接触到)v的某个边界(type)
|
||||
* @param type 边界类型
|
||||
* @param v 目标View,一般为ViewGroup(ListView,GridView等)
|
||||
*/
|
||||
void onReach(int type, View v);
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
/**移除回调
|
||||
* @author Lemon
|
||||
* @param <T>
|
||||
*/
|
||||
public interface OnRemoveListener<T> {
|
||||
|
||||
void onRemove(T object);
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
/**结果回调
|
||||
* @author Lemon
|
||||
* @param <T>
|
||||
*/
|
||||
public interface OnResultListener<T> {
|
||||
|
||||
void onResult(T result);
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
/**停止加载监听回调
|
||||
* @author Lemon
|
||||
* @use implements OnStopLoadListener
|
||||
*/
|
||||
public interface OnStopLoadListener {
|
||||
/**
|
||||
* 停止刷新
|
||||
*/
|
||||
void onStopRefresh();
|
||||
/**
|
||||
* 停止加载更多
|
||||
* @param isHaveMore 还有未加载的数据
|
||||
*/
|
||||
void onStopLoadMore(boolean isHaveMore);
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
/**Activity和Fragment的公共逻辑接口
|
||||
* @author Lemon
|
||||
* @use Activity或Fragment implements Presenter
|
||||
*/
|
||||
public interface Presenter {
|
||||
|
||||
static final String INTENT_TITLE = "INTENT_TITLE";
|
||||
static final String INTENT_ID = "INTENT_ID";
|
||||
static final String INTENT_TYPE = "INTENT_TYPE";
|
||||
static final String INTENT_PHONE = "INTENT_PHONE";
|
||||
static final String INTENT_PASSWORD = "INTENT_PASSWORD";
|
||||
static final String INTENT_VERIFY = "INTENT_VERIFY";
|
||||
static final String INTENT_USER_ID = "INTENT_USER_ID";
|
||||
static final String RESULT_DATA = "RESULT_DATA";
|
||||
static final String RESULT_ID = "RESULT_ID";
|
||||
static final String RESULT_TYPE = "RESULT_TYPE";
|
||||
static final String RESULT_PHONE = "RESULT_PHONE";
|
||||
static final String RESULT_PASSWORD = "RESULT_PASSWORD";
|
||||
static final String RESULT_VERIFY = "RESULT_VERIFY";
|
||||
static final String RESULT_USER_ID = "RESULT_USER_ID";
|
||||
|
||||
static final String ACTION_EXIT_APP = "ACTION_EXIT_APP";
|
||||
|
||||
/**
|
||||
* UI显示方法(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)
|
||||
* @must Activity-在子类onCreate方法内初始化View(setContentView)后调用;Fragment-在子类onCreateView方法内初始化View后调用
|
||||
*/
|
||||
void initView();
|
||||
/**
|
||||
* Data数据方法(存在数据获取或处理代码,但不存在事件监听代码)
|
||||
* @must Activity-在子类onCreate方法内初始化View(setContentView)后调用;Fragment-在子类onCreateView方法内初始化View后调用
|
||||
*/
|
||||
void initData();
|
||||
/**
|
||||
* Event事件方法(只要存在事件监听代码就是)
|
||||
* @must Activity-在子类onCreate方法内初始化View(setContentView)后调用;Fragment-在子类onCreateView方法内初始化View后调用
|
||||
*/
|
||||
void initEvent();
|
||||
|
||||
|
||||
/**
|
||||
* 是否存活(已启动且未被销毁)
|
||||
*/
|
||||
boolean isAlive();
|
||||
/**
|
||||
* 是否在运行
|
||||
*/
|
||||
boolean isRunning();
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.interfaces;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
/**View的逻辑接口
|
||||
* @author Lemon
|
||||
* @use implements ViewPresenter
|
||||
*/
|
||||
public interface ViewPresenter {
|
||||
|
||||
/**获取导航栏标题名
|
||||
* @return null - View.GONE; "" - View.GONE; "xxx" - "xxx"
|
||||
*/
|
||||
@Nullable
|
||||
public String getTitleName();
|
||||
|
||||
/**获取导航栏返回按钮名
|
||||
* @return null - default; "" - default; "xxx" - "xxx"
|
||||
*/
|
||||
@Nullable
|
||||
public String getReturnName();
|
||||
|
||||
/**获取导航栏前进按钮名
|
||||
* @return null - default; "" - default; "xxx" - "xxx"
|
||||
*/
|
||||
@Nullable
|
||||
public String getForwardName();
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
/**
|
||||
* 回调接口类所在包
|
||||
*/
|
||||
/**
|
||||
* @author Lemon
|
||||
* @use 通用使用方法:implements XXInterface
|
||||
*/
|
||||
package zuo.biao.library.interfaces;
|
@ -1,205 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.manager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import zuo.biao.library.util.JSON;
|
||||
import zuo.biao.library.util.Log;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
/**磁盘缓存类
|
||||
* @author Lemon
|
||||
* @param <T> 缓存的数据类
|
||||
* @use new Cache<T>(context, clazz, path).xxxMethod(...);具体参考.CacheManager
|
||||
*/
|
||||
public class Cache<T> {
|
||||
public static final String TAG = "Cache";
|
||||
|
||||
public Cache(Context context, Class<T> clazz, String path) {
|
||||
this(context, clazz, context.getSharedPreferences(StringUtil.getTrimedString(path), Context.MODE_PRIVATE));
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
private Context context;
|
||||
private Class<T> clazz;
|
||||
private SharedPreferences sp;
|
||||
public Cache(Context context, Class<T> clazz, SharedPreferences sp) {
|
||||
this.context = context;
|
||||
this.clazz = clazz;
|
||||
this.sp = sp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**获取列表大小
|
||||
* @return
|
||||
*/
|
||||
public int getSize() {
|
||||
Map<String, ?> map = sp.getAll();
|
||||
return map == null ? 0 : map.size();
|
||||
}
|
||||
|
||||
|
||||
/**保存
|
||||
* @param map
|
||||
*/
|
||||
public void saveList(Map<String, T> map) {
|
||||
if (map == null) {
|
||||
Log.e(TAG, "saveList map == null >> return;");
|
||||
return;
|
||||
}
|
||||
Set<String> keySet = map.keySet();
|
||||
if (keySet != null) {
|
||||
for (String id: keySet) {
|
||||
save(id, map.get(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**保存
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public void save(String key, T value) {
|
||||
if (StringUtil.isNotEmpty(key, true) == false || value == null) {
|
||||
Log.e(TAG, "save StringUtil.isNotEmpty(key, true) == false || value == null >> return;");
|
||||
return;
|
||||
}
|
||||
key = StringUtil.getTrimedString(key);
|
||||
|
||||
sp.edit().remove(key).putString(key, JSON.toJSONString(value)).commit();
|
||||
}
|
||||
|
||||
/**判断是否已存
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public boolean isContain(String key) {
|
||||
if (StringUtil.isNotEmpty(key, true) == false) {
|
||||
Log.e(TAG, "isContain StringUtil.isNotEmpty(key, true) == false >> return false;");
|
||||
return false;
|
||||
}
|
||||
|
||||
return sp.contains(StringUtil.getTrimedString(key));
|
||||
}
|
||||
|
||||
/**获取
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public T get(String key) {
|
||||
if (StringUtil.isNotEmpty(key, true) == false) {
|
||||
Log.e(TAG, "get (sp == null" +
|
||||
" || StringUtil.isNotEmpty(key, true) == false >> return null; ");
|
||||
return null;
|
||||
}
|
||||
|
||||
return JSON.parseObject(sp.getString(StringUtil.getTrimedString(key), null), clazz);
|
||||
}
|
||||
|
||||
|
||||
/**ROOT
|
||||
* 获取列表
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, String> getMap() {
|
||||
try {
|
||||
return (Map<String, String>) sp.getAll();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getMap try { return (Map<String, String>) sp.getAll();" +
|
||||
"}catch(Exception e) {\n " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**ROOT
|
||||
* 获取列表
|
||||
* @return
|
||||
*/
|
||||
public Set<String> getKeySet() {
|
||||
Map<String, String> map = getMap();
|
||||
return map == null ? null : map.keySet();
|
||||
}
|
||||
|
||||
/**ROOT
|
||||
* 获取列表
|
||||
* @param start < 0 ? all : [start, end]
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
public List<T> getValueList(int start, int end) {
|
||||
List<T> list = getAllValueList();
|
||||
return start < 0 || start > end || list == null || end >= list.size() ? list : list.subList(start, end);
|
||||
}
|
||||
/**ROOT
|
||||
* 获取列表,顺序由keyList指定
|
||||
* @param keyList
|
||||
* @return
|
||||
*/
|
||||
public List<T> getValueList(List<String> keyList) {
|
||||
if (keyList != null) {
|
||||
List<T> list = new ArrayList<T>();
|
||||
T data;
|
||||
for (String key : keyList) {
|
||||
data = get(key);
|
||||
if (data != null) {
|
||||
list.add(data);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**ROOT
|
||||
* 获取列表
|
||||
* @return
|
||||
*/
|
||||
public List<T> getAllValueList() {
|
||||
Map<String, String> map = getMap();
|
||||
if (map != null) {
|
||||
List<T> list = new ArrayList<T>();
|
||||
T data;
|
||||
for (String value : map.values()) {
|
||||
data = JSON.parseObject(value, clazz);
|
||||
if (data != null) {
|
||||
list.add(data);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**删除
|
||||
* @param key
|
||||
*/
|
||||
public void remove(String key) {
|
||||
if (StringUtil.isNotEmpty(key, true) == false) {
|
||||
Log.e(TAG, "deleteGroup context == null " +
|
||||
" || StringUtil.isNotEmpty(groupName, true) == fal >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
sp.edit().remove(StringUtil.getTrimedString(key)).commit();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,412 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.manager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.base.BaseApplication;
|
||||
import zuo.biao.library.util.DataKeeper;
|
||||
import zuo.biao.library.util.JSON;
|
||||
import zuo.biao.library.util.Log;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
|
||||
/**磁盘缓存管理类
|
||||
* @author Lemon
|
||||
* @use CacheManager.getInstance().xxxMethod(...);具体参考.BaseListActivity
|
||||
*/
|
||||
public class CacheManager {
|
||||
private static final String TAG = "CacheManager";
|
||||
|
||||
public static final String CACHE_PATH = DataKeeper.ROOT_SHARE_PREFS_ + "CACHE_PATH";
|
||||
|
||||
private Context context;
|
||||
private CacheManager(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
private static CacheManager manager;
|
||||
public static synchronized CacheManager getInstance() {
|
||||
if (manager == null) {
|
||||
manager = new CacheManager(BaseApplication.getInstance());
|
||||
}
|
||||
synchronized (CacheManager.class) {
|
||||
if (manager == null) {
|
||||
manager = new CacheManager(BaseApplication.getInstance());
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public <T> String getClassPath(Class<T> clazz) {
|
||||
return clazz == null ? null : CACHE_PATH + clazz.getName();
|
||||
}
|
||||
/**
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public <T> String getListPath(Class<T> clazz) {
|
||||
String classPath = getClassPath(clazz);
|
||||
return StringUtil.isNotEmpty(classPath, true) ? classPath + KEY_LIST : null;
|
||||
}
|
||||
/**
|
||||
* @param clazz
|
||||
* @param group
|
||||
* @return
|
||||
*/
|
||||
public <T> String getGroupPath(Class<T> clazz) {
|
||||
String classPath = getClassPath(clazz);
|
||||
return StringUtil.isNotEmpty(classPath, true) == false ? null : classPath + KEY_GROUP;
|
||||
}
|
||||
|
||||
private SharedPreferences getSharedPreferences(String path) {
|
||||
return StringUtil.isNotEmpty(path, true) == false
|
||||
? null : context.getSharedPreferences(StringUtil.getTrimedString(path), Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
public static final String KEY_LIST = "LIST";
|
||||
|
||||
/**
|
||||
* 数据分组,自定义
|
||||
*/
|
||||
public static final String KEY_GROUP = "GROUP";
|
||||
/**
|
||||
* 分组中列表每页最大数量
|
||||
*/
|
||||
public static final int MAX_PAGE_SIZE = 10;
|
||||
|
||||
/**获取列表
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public <T> List<T> getAllList(Class<T> clazz) {
|
||||
return getList(clazz, -1, 0);
|
||||
}
|
||||
/**获取列表
|
||||
* @param clazz
|
||||
* @param start
|
||||
* @return
|
||||
*/
|
||||
public <T> List<T> getList(Class<T> clazz, int start, int pageSize) {
|
||||
return getList(clazz, null, start, pageSize);
|
||||
}
|
||||
/**获取列表
|
||||
* @param clazz
|
||||
* @param group
|
||||
* @return
|
||||
*/
|
||||
public <T> List<T> getAllList(Class<T> clazz, String group) {
|
||||
return StringUtil.isNotEmpty(group, true) ? getList(clazz, group, -1, 0) : null;
|
||||
}
|
||||
/**获取列表
|
||||
* @param clazz
|
||||
* @param group == null ? all : in group
|
||||
* @param start < 0 ? all in group : subList(start, end)
|
||||
* @param count > 0 ? all in group : subList(start, end)
|
||||
* @return
|
||||
*/
|
||||
public <T> List<T> getList(Class<T> clazz, String group, int start, int count) {
|
||||
Log.i(TAG, "\n\n<<<<<<<<<<<<<<<<\ngetList group = " + group +"; start = " + start + "; count = " + count);
|
||||
if (count <= 0 || clazz == null) {
|
||||
Log.e(TAG, "getList count <= 0 || clazz == null >> return null;");
|
||||
return null;
|
||||
}
|
||||
Cache<T> cacheList = new Cache<T>(context, clazz, getClassPath(clazz) + KEY_LIST);
|
||||
|
||||
if (StringUtil.isNotEmpty(group, true) == false) {
|
||||
return cacheList == null ? null : cacheList.getValueList(start, start + count);
|
||||
}
|
||||
|
||||
List<String> idList = getIdList(clazz, group);
|
||||
final int totalCount = idList == null ? 0 : idList.size();
|
||||
Log.i(TAG, "getList idList.size() = " + totalCount);
|
||||
if (totalCount <= 0) {
|
||||
Log.e(TAG, "getList totalCount <= 0 >> return null;");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (start >= 0) {
|
||||
Log.i(TAG, "getList start >= 0 >> ");
|
||||
|
||||
int end = start + count;
|
||||
if (end > totalCount) {
|
||||
end = totalCount;
|
||||
}
|
||||
Log.i(TAG, "getList end = " + end);
|
||||
if (end <= start) {
|
||||
Log.e(TAG, "getList end <= start >> return null;");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (start > 0 || end < totalCount) {
|
||||
Log.i(TAG, "getList start > 0 || end < totalCount >> idList = idList.subList(" + start + "," + end + "); >>");
|
||||
idList = idList.subList(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
List<T> list = new ArrayList<T>();
|
||||
T data;
|
||||
for (String id : idList) {
|
||||
data = cacheList.get(id);
|
||||
if (data != null) {
|
||||
list.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
Log.i(TAG, "getList return list; list.size() = " + list.size() + "\n>>>>>>>>>>>>>>>>>>>>>>\n\n");
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**获取单个值
|
||||
* @param clazz
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public <T> T get(Class<T> clazz, String id) {
|
||||
Cache<T> cacheList = clazz == null
|
||||
? null : new Cache<T>(context, clazz, getClassPath(clazz) + KEY_LIST);
|
||||
return cacheList == null ? null : cacheList.get(id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**获取id列表
|
||||
* @param clazz
|
||||
* @param group
|
||||
* @return
|
||||
*/
|
||||
public <T> List<String> getIdList(Class<T> clazz, String group) {
|
||||
SharedPreferences sp = getSharedPreferences(
|
||||
getClassPath(clazz) + KEY_GROUP);
|
||||
return sp == null ? null : JSON.parseArray(sp.getString(StringUtil.getTrimedString(group), null), String.class);
|
||||
}
|
||||
|
||||
/**保存列表
|
||||
* @param clazz 类
|
||||
* @param map 数据表
|
||||
*/
|
||||
public <T> void addList(Class<T> clazz, LinkedHashMap<String, T> map) {
|
||||
saveList(clazz, null, map, 0, 0);
|
||||
}
|
||||
/**添加列表
|
||||
* @param clazz 类
|
||||
* @param group 分组
|
||||
* @param map 数据表
|
||||
*/
|
||||
public <T> void addList(Class<T> clazz, String group, LinkedHashMap<String, T> map) {
|
||||
addList(clazz, group, map, -1);
|
||||
}
|
||||
/**添加列表
|
||||
* @param clazz 类
|
||||
* @param group 分组
|
||||
* @param map 数据表
|
||||
* @param pageSize 每页大小
|
||||
*/
|
||||
public <T> void addList(Class<T> clazz, String group, LinkedHashMap<String, T> map, int pageSize) {
|
||||
if (StringUtil.isNotEmpty(group, true) == false) {
|
||||
Log.e(TAG, "addList StringUtil.isNotEmpty(group, true) == false >> return;");
|
||||
return;
|
||||
}
|
||||
saveList(clazz, group, map, -1, pageSize);
|
||||
}
|
||||
/**保存列表
|
||||
* @param clazz 类
|
||||
* @param group 分组
|
||||
* @param map 数据表
|
||||
* @param start 存储起始位置,[start, start + map.size()]中原有的将被替换. start = start < 0 ? idList.size() : start;
|
||||
* @param pageSize 每页大小
|
||||
*/
|
||||
public <T> void saveList(Class<T> clazz, String group, LinkedHashMap<String, T> map, int start, int pageSize) {
|
||||
Log.i(TAG, "\n\n <<<<<<<<<<<<<<<<<\nsaveList group = " + group + "; start = " + start + "; pageSize = " + pageSize);
|
||||
if (clazz == null || map == null || map.size() <= 0) {
|
||||
Log.e(TAG, "saveList clazz == null || map == null || map.size() <= 0 >> return;");
|
||||
return;
|
||||
}
|
||||
final String CLASS_PATH = getClassPath(clazz);
|
||||
|
||||
if (StringUtil.isNotEmpty(group, true)) {
|
||||
group = StringUtil.getTrimedString(group);
|
||||
|
||||
Log.i(TAG, "saveList group = " + group + "; map.size() = " + map.size()
|
||||
+ "; start = " + start +"; pageSize = " + pageSize);
|
||||
List<String> newIdList = new ArrayList<String>(map.keySet());//用String而不是Long,因为订单Order的id超出Long的最大值
|
||||
|
||||
Log.i(TAG, "saveList newIdList.size() = " + newIdList.size() + "; start save <<<<<<<<<<<<<<<<<\n ");
|
||||
|
||||
|
||||
//保存至分组<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
SharedPreferences sp = getSharedPreferences(CLASS_PATH + KEY_GROUP);
|
||||
// sp.edit().putString(KEY_GROUP, group);
|
||||
Editor editor = sp.edit();
|
||||
|
||||
Log.i(TAG, "\n saveList pageSize = " + pageSize + " <<<<<<<<");
|
||||
//列表每页大小
|
||||
if (pageSize > 0) {
|
||||
if (pageSize > MAX_PAGE_SIZE) {
|
||||
pageSize = MAX_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
Log.i(TAG, "\n saveList pageSize = " + pageSize + ">>>>>>>>>");
|
||||
|
||||
//id列表
|
||||
List<String> idList = JSON.parseArray(sp.getString(group, null), String.class);
|
||||
if (idList == null) {
|
||||
idList = new ArrayList<String>();
|
||||
}
|
||||
if (start < 0) {
|
||||
start = idList.size();
|
||||
}
|
||||
Log.i(TAG, "\n saveList idList.size() = " + idList.size() + " <<<<<<<<");
|
||||
String id;
|
||||
for (int i = start; i < start + newIdList.size(); i++) {
|
||||
id = newIdList.get(i - start);
|
||||
if (id == null || id.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (idList.contains(id)) {
|
||||
idList.remove(id);//位置发生变化
|
||||
}
|
||||
if (i < idList.size()) {
|
||||
idList.set(i, id);
|
||||
} else {
|
||||
idList.add(id);
|
||||
}
|
||||
}
|
||||
editor.remove(group).putString(group, JSON.toJSONString(idList)).commit();
|
||||
|
||||
Log.i(TAG, "\n saveList idList.size() = " + idList.size() + " >>>>>>>>");
|
||||
}
|
||||
|
||||
//保存至分组>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
//保存所有数据<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
Cache<T> cache = new Cache<T>(context, clazz, CLASS_PATH + KEY_LIST);
|
||||
cache.saveList(map);
|
||||
//保存所有数据>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
Log.i(TAG, "saveList cache.getSize() = " + cache.getSize() + "; end save \n>>>>>>>>>>>>>>>>>> \n\n");
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
/**保存
|
||||
* 未完成
|
||||
* @param clazz
|
||||
* @param data 数据
|
||||
* @param id
|
||||
*/
|
||||
public <T> void save(Class<T> clazz, T data, String id) {
|
||||
save(clazz, data, id, null);
|
||||
}
|
||||
/**ROOT
|
||||
* 保存
|
||||
* @param clazz
|
||||
* @param data 数据
|
||||
* @param id
|
||||
* @param group 分组
|
||||
*/
|
||||
public <T> void save(Class<T> clazz, T data, String id, String group) {
|
||||
if (data == null || StringUtil.isNotEmpty(id, true) == false) {
|
||||
Log.e(id, "save data == null || StringUtil.isNotEmpty(id, true) == false >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
new Cache<T>(context, clazz, getListPath(clazz)).save(id, data);
|
||||
|
||||
SharedPreferences sp = getSharedPreferences(getGroupPath(clazz));
|
||||
if (sp != null) {
|
||||
group = StringUtil.getTrimedString(group);
|
||||
|
||||
Log.i(TAG, "save sp != null >> save to group");
|
||||
List<String> idList = getIdList(clazz, group);
|
||||
if (idList == null) {
|
||||
idList = new ArrayList<String>();
|
||||
}
|
||||
if (idList.contains(id) == false) {
|
||||
Log.i(TAG, "save idList.contains(id) == false >> add");
|
||||
idList.add(0, id);
|
||||
sp.edit().remove(group).putString(group, JSON.toJSONString(idList)).commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**清空类
|
||||
* @param <T>
|
||||
* @param clazz
|
||||
*/
|
||||
public <T> void clear(Class<T> clazz) {
|
||||
clear(getSharedPreferences(getListPath(clazz)));
|
||||
}
|
||||
/**清空群组
|
||||
* @param <T>
|
||||
* @param clazz
|
||||
* @param group
|
||||
*/
|
||||
public <T> void clear(Class<T> clazz, String group) {
|
||||
clear(clazz, group, false);
|
||||
}
|
||||
/**清空群组
|
||||
* @param clazz
|
||||
* @param group
|
||||
* @param removeAllInGroup 删除群组内所有id对应数据
|
||||
* @param <T>
|
||||
*/
|
||||
public <T> void clear(Class<T> clazz, String group, boolean removeAllInGroup) {
|
||||
Log.i(TAG, "clear group = " + group + "; removeAllInGroup = " + removeAllInGroup);
|
||||
List<String> list = removeAllInGroup == false ? null : getIdList(clazz, group);
|
||||
if (list != null) {
|
||||
Cache<T> cache = new Cache<T>(context, clazz, getListPath(clazz));
|
||||
for (String id : list) {
|
||||
cache.remove(id);
|
||||
}
|
||||
}
|
||||
clear(getSharedPreferences(getGroupPath(clazz)));
|
||||
}
|
||||
/**清空
|
||||
* @param sp
|
||||
*/
|
||||
public void clear(SharedPreferences sp) {
|
||||
if (sp == null) {
|
||||
Log.e(TAG, "clearList sp == null >> return;");
|
||||
return;
|
||||
}
|
||||
sp.edit().clear().commit();
|
||||
}
|
||||
|
||||
public <T> void remove(Class<T> clazz, String id) {
|
||||
if (clazz == null) {
|
||||
Log.e(TAG, "remove clazz == null >> return;");
|
||||
return;
|
||||
}
|
||||
new Cache<T>(context, clazz, getListPath(clazz)).remove(id);
|
||||
}
|
||||
|
||||
}
|
@ -1,207 +0,0 @@
|
||||
package zuo.biao.library.manager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.model.City;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
|
||||
/**地区管理类
|
||||
* @author Lemon
|
||||
* @use CityDB.getInstance(...).xxMethod(...)
|
||||
*/
|
||||
public class CityDB {
|
||||
public static final String CITY_DB_NAME = "city.db";
|
||||
private static final String CITY_TABLE_NAME = "city";
|
||||
private SQLiteDatabase db;
|
||||
|
||||
public CityDB(Context context, String path) {
|
||||
db = context.openOrCreateDatabase(path, Context.MODE_PRIVATE, null);
|
||||
}
|
||||
|
||||
private static CityDB cityDB;
|
||||
public static synchronized CityDB getInstance(Context context, String packageName) {
|
||||
if (cityDB == null) {
|
||||
cityDB = openCityDB(context, packageName);
|
||||
}
|
||||
return cityDB;
|
||||
}
|
||||
|
||||
private static CityDB openCityDB(Context context, String packageName) {
|
||||
String path = "/data"
|
||||
+ Environment.getDataDirectory().getAbsolutePath()
|
||||
+ File.separator + packageName + File.separator
|
||||
+ CityDB.CITY_DB_NAME;
|
||||
File db = new File(path);
|
||||
if (!db.exists()) {
|
||||
try {
|
||||
InputStream is = context.getAssets().open("city.db");
|
||||
FileOutputStream fos = new FileOutputStream(db);
|
||||
int len = -1;
|
||||
byte[] buffer = new byte[1024];
|
||||
while ((len = is.read(buffer)) != -1) {
|
||||
fos.write(buffer, 0, len);
|
||||
fos.flush();
|
||||
}
|
||||
fos.close();
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
return new CityDB(context, path);
|
||||
}
|
||||
|
||||
|
||||
public List<City> getAllCity() {
|
||||
List<City> list = new ArrayList<City>();
|
||||
Cursor c = db.rawQuery("SELECT * from " + CITY_TABLE_NAME, null);
|
||||
while (c.moveToNext()) {
|
||||
String province = c.getString(c.getColumnIndex("province"));
|
||||
String city = c.getString(c.getColumnIndex("city"));
|
||||
Double latitude = c.getDouble(c.getColumnIndex("latitude"));
|
||||
Double longitude = c.getDouble(c.getColumnIndex("longitude"));
|
||||
City item = new City(province, city, latitude, longitude);
|
||||
list.add(item);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public List<String> getAllProvince() {
|
||||
|
||||
List<String> list = new ArrayList<String>();
|
||||
|
||||
Cursor c = db.rawQuery("SELECT distinct province from " + CITY_TABLE_NAME, null);
|
||||
while (c.moveToNext()) {
|
||||
String province = c.getString(c.getColumnIndex("province"));
|
||||
list.add(province);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 拿到省的所有 地级市
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<String> getProvinceAllCity(String province) {
|
||||
province = StringUtil.getTrimedString(province);
|
||||
if (province.length() <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<String>();
|
||||
|
||||
Cursor c = db.rawQuery("SELECT distinct city from " + CITY_TABLE_NAME + " where province = ? ", new String[]{province});
|
||||
while (c.moveToNext()) {
|
||||
String city = c.getString(c.getColumnIndex("city"));
|
||||
list.add(city);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拿到所有的 县或区
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<String> getAllCountry(String province, String city) {
|
||||
province = StringUtil.getTrimedString(province);
|
||||
if (province.length() <= 0) {
|
||||
return null;
|
||||
}
|
||||
city = StringUtil.getTrimedString(city);
|
||||
if (city.length() <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<String>();
|
||||
|
||||
Cursor c = db.rawQuery("SELECT country from " + CITY_TABLE_NAME + " where province = ? and city = ?", new String[]{province, city});
|
||||
while (c.moveToNext()) {
|
||||
String country = c.getString(c.getColumnIndex("country"));
|
||||
list.add(country);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public City getCity(String city) {
|
||||
if (TextUtils.isEmpty(city))
|
||||
return null;
|
||||
City item = getCityInfo(parseName(city));
|
||||
if (item == null) {
|
||||
item = getCityInfo(city);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* 去掉市或县搜索
|
||||
*
|
||||
* @param city
|
||||
* @return
|
||||
*/
|
||||
private String parseName(String city) {
|
||||
if (city.contains("市")) {// 如果为空就去掉市字再试试
|
||||
String subStr[] = city.split("市");
|
||||
city = subStr[0];
|
||||
} else if (city.contains("县")) {// 或者去掉县字再试试
|
||||
String subStr[] = city.split("县");
|
||||
city = subStr[0];
|
||||
}
|
||||
return city;
|
||||
}
|
||||
|
||||
private City getCityInfo(String city) {
|
||||
Cursor c = db.rawQuery("SELECT * from " + CITY_TABLE_NAME
|
||||
+ " where city=?", new String[]{city});
|
||||
if (c.moveToFirst()) {
|
||||
String province = c.getString(c.getColumnIndex("province"));
|
||||
String name = c.getString(c.getColumnIndex("city"));
|
||||
Double latitude = c.getDouble(c.getColumnIndex("latitude"));
|
||||
Double longitude = c.getDouble(c.getColumnIndex("longitude"));
|
||||
|
||||
City item = new City(province, name, latitude, longitude);
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询附近的城市
|
||||
* 画正方形
|
||||
*/
|
||||
public List<String> getNearbyCityList(String sCity) {
|
||||
City city = getCity(sCity);
|
||||
List<String> nearbyCitysList = new ArrayList<String>();
|
||||
//根据常跑地信息画正方形地域
|
||||
double lat = city.getLatitude() + 0.9;
|
||||
double lon = city.getLongitude() + 0.9;
|
||||
double lat1 = city.getLatitude() - 0.9;
|
||||
double lon1 = city.getLongitude() - 0.9;
|
||||
|
||||
Cursor c = db.rawQuery("SELECT * from " + CITY_TABLE_NAME + " WHERE LATITUDE < " + lat + " AND LATITUDE > " + lat1 +
|
||||
" AND LONGITUDE <" + lon + " AND LONGITUDE > " + lon1, null);
|
||||
while (c.moveToNext()) {
|
||||
String nearbyCity = c.getString(c.getColumnIndex("city"));
|
||||
nearbyCitysList.add(nearbyCity);
|
||||
}
|
||||
return nearbyCitysList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,359 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.manager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.CookieHandler;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import zuo.biao.library.base.BaseApplication;
|
||||
import zuo.biao.library.model.Parameter;
|
||||
import zuo.biao.library.util.Log;
|
||||
import zuo.biao.library.util.SSLUtil;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.squareup.okhttp.FormEncodingBuilder;
|
||||
import com.squareup.okhttp.OkHttpClient;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
/**HTTP请求管理类
|
||||
* @author Lemon
|
||||
* @use HttpManager.getInstance().get(...)或HttpManager.getInstance().post(...) > 在回调方法onHttpRequestSuccess和onHttpRequestError处理HTTP请求结果
|
||||
* @must 解决getToken,getResponseCode,getResponseData中的TODO
|
||||
*/
|
||||
public class HttpManager {
|
||||
private static final String TAG = "HttpManager";
|
||||
|
||||
/**网络请求回调接口
|
||||
*/
|
||||
public interface OnHttpResponseListener {
|
||||
/**
|
||||
* @param requestCode 请求码,自定义,在发起请求的类中可以用requestCode来区分各个请求
|
||||
* @param resultJson 服务器返回的Json串
|
||||
* @param e 异常
|
||||
*/
|
||||
void onHttpResponse(int requestCode, String resultJson, Exception e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Context context;
|
||||
private static HttpManager instance;// 单例
|
||||
private static SSLSocketFactory socketFactory;// 单例
|
||||
private HttpManager(Context context) {
|
||||
this.context = context;
|
||||
|
||||
try {
|
||||
//TODO 初始化自签名,demo.cer(这里demo.cer是空文件)为服务器生成的自签名证书,存放于assets目录下,如果不需要自签名可删除
|
||||
socketFactory = SSLUtil.getSSLSocketFactory(context.getAssets().open("demo.cer"));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "HttpManager try {" +
|
||||
" socketFactory = SSLUtil.getSSLSocketFactory(context.getAssets().open(\"demo.cer\"));\n" +
|
||||
"\t\t} catch (Exception e) {\n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static HttpManager getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new HttpManager(BaseApplication.getInstance());
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 列表首页页码。有些服务器设置为1,即列表页码从1开始
|
||||
*/
|
||||
public static final int PAGE_NUM_0 = 0;
|
||||
|
||||
public static final String KEY_TOKEN = "token";
|
||||
public static final String KEY_COOKIE = "cookie";
|
||||
|
||||
|
||||
/**GET请求
|
||||
* @param paramList 请求参数列表,(可以一个键对应多个值)
|
||||
* @param url 接口url
|
||||
* @param requestCode
|
||||
* 请求码,类似onActivityResult中请求码,当同一activity中以实现接口方式发起多个网络请求时,请求结束后都会回调
|
||||
* {@link OnHttpResponseListener#onHttpResponse(int, String, Exception)}<br>
|
||||
* 在发起请求的类中可以用requestCode来区分各个请求
|
||||
* @param listener
|
||||
*/
|
||||
public void get(final List<Parameter> paramList, final String url,
|
||||
final int requestCode, final OnHttpResponseListener listener) {
|
||||
|
||||
new AsyncTask<Void, Void, Exception>() {
|
||||
|
||||
String result;
|
||||
@Override
|
||||
protected Exception doInBackground(Void... params) {
|
||||
OkHttpClient client = getHttpClient(url);
|
||||
if (client == null) {
|
||||
return new Exception(TAG + ".get AsyncTask.doInBackground client == null >> return;");
|
||||
}
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(StringUtil.getNoBlankString(url));
|
||||
if (paramList != null) {
|
||||
Parameter parameter;
|
||||
for (int i = 0; i < paramList.size(); i++) {
|
||||
parameter = paramList.get(i);
|
||||
sb.append(i <= 0 ? "?" : "&");
|
||||
sb.append(StringUtil.getTrimedString(parameter.key));
|
||||
sb.append("=");
|
||||
sb.append(StringUtil.getTrimedString(parameter.value));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
result = getResponseJson(client, new Request.Builder()
|
||||
.addHeader(KEY_TOKEN, getToken(url))
|
||||
.url(sb.toString()).build());
|
||||
//TODO 注释或删除以下 测试HttpRequest.getUser接口的数据
|
||||
result = "{\"code\":100,\"data\":{\"id\":1,\"name\":\"TestName\",\"phone\":\"1234567890\"}}";
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "get AsyncTask.doInBackground try { result = getResponseJson(..." +
|
||||
"} catch (Exception e) {\n" + e.getMessage());
|
||||
return e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Exception exception) {
|
||||
super.onPostExecute(exception);
|
||||
listener.onHttpResponse(requestCode, result, exception);
|
||||
}
|
||||
|
||||
}.execute();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**POST请求
|
||||
* @param paramList 请求参数列表,(可以一个键对应多个值)
|
||||
* @param url 接口url
|
||||
* @param requestCode
|
||||
* 请求码,类似onActivityResult中请求码,当同一activity中以实现接口方式发起多个网络请求时,请求结束后都会回调
|
||||
* {@link OnHttpResponseListener#onHttpResponse(int, String, Exception)}<br>
|
||||
* 在发起请求的类中可以用requestCode来区分各个请求
|
||||
* @param listener
|
||||
*/
|
||||
public void post(final List<Parameter> paramList, final String url,
|
||||
final int requestCode, final OnHttpResponseListener listener) {
|
||||
|
||||
new AsyncTask<Void, Void, Exception>() {
|
||||
|
||||
String result;
|
||||
@Override
|
||||
protected Exception doInBackground(Void... params) {
|
||||
OkHttpClient client = getHttpClient(url);
|
||||
if (client == null) {
|
||||
return new Exception(TAG + ".post AsyncTask.doInBackground client == null >> return;");
|
||||
}
|
||||
|
||||
FormEncodingBuilder fBuilder = new FormEncodingBuilder();
|
||||
if (paramList != null) {
|
||||
for (Parameter p : paramList) {
|
||||
fBuilder.add(StringUtil.getTrimedString(p.key), StringUtil.getTrimedString(p.value));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
result = getResponseJson(client, new Request.Builder()
|
||||
.addHeader(KEY_TOKEN, getToken(url)).url(StringUtil.getNoBlankString(url))
|
||||
.post(fBuilder.build()).build());
|
||||
//TODO 注释或删除以下 测试HttpRequest.register接口的数据
|
||||
result = "{\"code\":102}";
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "post AsyncTask.doInBackground try { result = getResponseJson(..." +
|
||||
"} catch (Exception e) {\n" + e.getMessage());
|
||||
return e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Exception exception) {
|
||||
super.onPostExecute(exception);
|
||||
listener.onHttpResponse(requestCode, result, exception);
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
|
||||
|
||||
//httpGet/httpPost 内调用方法 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
private OkHttpClient getHttpClient(String url) {
|
||||
Log.i(TAG, "getHttpClient url = " + url);
|
||||
if (StringUtil.isNotEmpty(url, true) == false) {
|
||||
Log.e(TAG, "getHttpClient StringUtil.isNotEmpty(url, true) == false >> return null;");
|
||||
return null;
|
||||
}
|
||||
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
client.setCookieHandler(new HttpHead());
|
||||
client.setConnectTimeout(15, TimeUnit.SECONDS);
|
||||
client.setWriteTimeout(10, TimeUnit.SECONDS);
|
||||
client.setReadTimeout(10, TimeUnit.SECONDS);
|
||||
//添加信任https证书,用于自签名,不需要可删除
|
||||
if (url.startsWith(StringUtil.URL_PREFIXs) && socketFactory != null) {
|
||||
client.setSslSocketFactory(socketFactory);
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param paramList
|
||||
* @return
|
||||
*/
|
||||
public String getToken(String tag) {
|
||||
return context.getSharedPreferences(KEY_TOKEN, Context.MODE_PRIVATE).getString(KEY_TOKEN + tag, "");
|
||||
}
|
||||
/**
|
||||
* @param tag
|
||||
* @param value
|
||||
*/
|
||||
public void saveToken(String tag, String value) {
|
||||
context.getSharedPreferences(KEY_TOKEN, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.remove(KEY_TOKEN + tag)
|
||||
.putString(KEY_TOKEN + tag, value)
|
||||
.commit();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getCookie() {
|
||||
return context.getSharedPreferences(KEY_COOKIE, Context.MODE_PRIVATE).getString(KEY_COOKIE, "");
|
||||
}
|
||||
/**
|
||||
* @param value
|
||||
*/
|
||||
public void saveCookie(String value) {
|
||||
context.getSharedPreferences(KEY_COOKIE, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.remove(KEY_COOKIE)
|
||||
.putString(KEY_COOKIE, value)
|
||||
.commit();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param client
|
||||
* @param request
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private String getResponseJson(OkHttpClient client, Request request) throws Exception {
|
||||
if (client == null || request == null) {
|
||||
Log.e(TAG, "getResponseJson client == null || request == null >> return null;");
|
||||
return null;
|
||||
}
|
||||
Response response = client.newCall(request).execute();
|
||||
return response.isSuccessful() ? response.body().string() : null;
|
||||
}
|
||||
|
||||
/**从object中获取key对应的值
|
||||
* *获取如果T是基本类型容易崩溃,所以需要try-catch
|
||||
* @param json
|
||||
* @param key
|
||||
* @return
|
||||
* @throws JSONException
|
||||
*/
|
||||
public <T> T getValue(String json, String key) throws JSONException {
|
||||
return getValue(new JSONObject(json), key);
|
||||
}
|
||||
/**从object中获取key对应的值
|
||||
* *获取如果T是基本类型容易崩溃,所以需要try-catch
|
||||
* @param object
|
||||
* @param key
|
||||
* @return
|
||||
* @throws JSONException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getValue(JSONObject object, String key) throws JSONException {
|
||||
return (T) object.get(key);
|
||||
}
|
||||
|
||||
//httpGet/httpPost 内调用方法 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
/**http请求头
|
||||
*/
|
||||
public class HttpHead extends CookieHandler {
|
||||
public HttpHead() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) throws IOException {
|
||||
String cookie = getCookie();
|
||||
Map<String, List<String>> map = new HashMap<String, List<String>>();
|
||||
map.putAll(requestHeaders);
|
||||
if (!TextUtils.isEmpty(cookie)) {
|
||||
List<String> cList = new ArrayList<String>();
|
||||
cList.add(cookie);
|
||||
map.put("Cookie", cList);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException {
|
||||
List<String> list = responseHeaders.get("Set-Cookie");
|
||||
if (list != null) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
String cookie = list.get(i);
|
||||
if (cookie.startsWith("JSESSIONID")) {
|
||||
saveCookie(list.get(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,566 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 readyState Software Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package zuo.biao.library.manager;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout.LayoutParams;
|
||||
|
||||
/**系统栏背景管理器
|
||||
* Class to manage status and navigation bar tint effects when using KitKat
|
||||
* translucent system UI modes.
|
||||
*/
|
||||
public class SystemBarTintManager {
|
||||
|
||||
static {
|
||||
// Android allows a system property to override the presence of the navigation bar.
|
||||
// Used by the emulator.
|
||||
// See https://github.com/android/platform_frameworks_base/blob/master/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java#L1076
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
try {
|
||||
@SuppressWarnings("rawtypes")
|
||||
Class c = Class.forName("android.os.SystemProperties");
|
||||
@SuppressWarnings("unchecked")
|
||||
Method m = c.getDeclaredMethod("get", String.class);
|
||||
m.setAccessible(true);
|
||||
sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
|
||||
} catch (Throwable e) {
|
||||
sNavBarOverride = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The default system bar tint color value.
|
||||
*/
|
||||
public static final int DEFAULT_TINT_COLOR = 0x99000000;
|
||||
|
||||
private static String sNavBarOverride;
|
||||
|
||||
private final SystemBarConfig mConfig;
|
||||
private boolean mStatusBarAvailable;
|
||||
private boolean mNavBarAvailable;
|
||||
private boolean mStatusBarTintEnabled;
|
||||
private boolean mNavBarTintEnabled;
|
||||
private View mStatusBarTintView;
|
||||
private View mNavBarTintView;
|
||||
|
||||
/**
|
||||
* Constructor. Call this in the host activity onCreate method after its
|
||||
* content view has been set. You should always create new instances when
|
||||
* the host activity is recreated.
|
||||
*
|
||||
* @param activity The host activity.
|
||||
*/
|
||||
@TargetApi(19)
|
||||
public SystemBarTintManager(Activity activity) {
|
||||
|
||||
Window win = activity.getWindow();
|
||||
ViewGroup decorViewGroup = (ViewGroup) win.getDecorView();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
// check theme attrs
|
||||
int[] attrs = {android.R.attr.windowTranslucentStatus,
|
||||
android.R.attr.windowTranslucentNavigation};
|
||||
TypedArray a = activity.obtainStyledAttributes(attrs);
|
||||
try {
|
||||
mStatusBarAvailable = a.getBoolean(0, false);
|
||||
mNavBarAvailable = a.getBoolean(1, false);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
// check window flags
|
||||
WindowManager.LayoutParams winParams = win.getAttributes();
|
||||
int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
|
||||
if ((winParams.flags & bits) != 0) {
|
||||
mStatusBarAvailable = true;
|
||||
}
|
||||
bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
|
||||
if ((winParams.flags & bits) != 0) {
|
||||
mNavBarAvailable = true;
|
||||
}
|
||||
}
|
||||
|
||||
mConfig = new SystemBarConfig(activity, mStatusBarAvailable, mNavBarAvailable);
|
||||
// device might not have virtual navigation keys
|
||||
if (!mConfig.hasNavigtionBar()) {
|
||||
mNavBarAvailable = false;
|
||||
}
|
||||
|
||||
if (mStatusBarAvailable) {
|
||||
setupStatusBarView(activity, decorViewGroup);
|
||||
}
|
||||
if (mNavBarAvailable) {
|
||||
setupNavBarView(activity, decorViewGroup);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable tinting of the system status bar.
|
||||
*
|
||||
* If the platform is running Jelly Bean or earlier, or translucent system
|
||||
* UI modes have not been enabled in either the theme or via window flags,
|
||||
* then this method does nothing.
|
||||
*
|
||||
* @param enabled True to enable tinting, false to disable it (default).
|
||||
*/
|
||||
public void setStatusBarTintEnabled(boolean enabled) {
|
||||
mStatusBarTintEnabled = enabled;
|
||||
if (mStatusBarAvailable) {
|
||||
mStatusBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable tinting of the system navigation bar.
|
||||
*
|
||||
* If the platform does not have soft navigation keys, is running Jelly Bean
|
||||
* or earlier, or translucent system UI modes have not been enabled in either
|
||||
* the theme or via window flags, then this method does nothing.
|
||||
*
|
||||
* @param enabled True to enable tinting, false to disable it (default).
|
||||
*/
|
||||
public void setNavigationBarTintEnabled(boolean enabled) {
|
||||
mNavBarTintEnabled = enabled;
|
||||
if (mNavBarAvailable) {
|
||||
mNavBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified color tint to all system UI bars.
|
||||
*
|
||||
* @param color The color of the background tint.
|
||||
*/
|
||||
public void setTintColor(int color) {
|
||||
setStatusBarTintColor(color);
|
||||
setNavigationBarTintColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable or color resource to all system UI bars.
|
||||
*
|
||||
* @param res The identifier of the resource.
|
||||
*/
|
||||
public void setTintResource(int res) {
|
||||
setStatusBarTintResource(res);
|
||||
setNavigationBarTintResource(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable to all system UI bars.
|
||||
*
|
||||
* @param drawable The drawable to use as the background, or null to remove it.
|
||||
*/
|
||||
public void setTintDrawable(Drawable drawable) {
|
||||
setStatusBarTintDrawable(drawable);
|
||||
setNavigationBarTintDrawable(drawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified alpha to all system UI bars.
|
||||
*
|
||||
* @param alpha The alpha to use
|
||||
*/
|
||||
public void setTintAlpha(float alpha) {
|
||||
setStatusBarAlpha(alpha);
|
||||
setNavigationBarAlpha(alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified color tint to the system status bar.
|
||||
*
|
||||
* @param color The color of the background tint.
|
||||
*/
|
||||
public void setStatusBarTintColor(int color) {
|
||||
if (mStatusBarAvailable) {
|
||||
mStatusBarTintView.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable or color resource to the system status bar.
|
||||
*
|
||||
* @param res The identifier of the resource.
|
||||
*/
|
||||
public void setStatusBarTintResource(int res) {
|
||||
if (mStatusBarAvailable) {
|
||||
mStatusBarTintView.setBackgroundResource(res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable to the system status bar.
|
||||
*
|
||||
* @param drawable The drawable to use as the background, or null to remove it.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setStatusBarTintDrawable(Drawable drawable) {
|
||||
if (mStatusBarAvailable) {
|
||||
mStatusBarTintView.setBackgroundDrawable(drawable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified alpha to the system status bar.
|
||||
*
|
||||
* @param alpha The alpha to use
|
||||
*/
|
||||
@TargetApi(11)
|
||||
public void setStatusBarAlpha(float alpha) {
|
||||
if (mStatusBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mStatusBarTintView.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified color tint to the system navigation bar.
|
||||
*
|
||||
* @param color The color of the background tint.
|
||||
*/
|
||||
public void setNavigationBarTintColor(int color) {
|
||||
if (mNavBarAvailable) {
|
||||
mNavBarTintView.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable or color resource to the system navigation bar.
|
||||
*
|
||||
* @param res The identifier of the resource.
|
||||
*/
|
||||
public void setNavigationBarTintResource(int res) {
|
||||
if (mNavBarAvailable) {
|
||||
mNavBarTintView.setBackgroundResource(res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable to the system navigation bar.
|
||||
*
|
||||
* @param drawable The drawable to use as the background, or null to remove it.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setNavigationBarTintDrawable(Drawable drawable) {
|
||||
if (mNavBarAvailable) {
|
||||
mNavBarTintView.setBackgroundDrawable(drawable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified alpha to the system navigation bar.
|
||||
*
|
||||
* @param alpha The alpha to use
|
||||
*/
|
||||
@TargetApi(11)
|
||||
public void setNavigationBarAlpha(float alpha) {
|
||||
if (mNavBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mNavBarTintView.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the system bar configuration.
|
||||
*
|
||||
* @return The system bar configuration for the current device configuration.
|
||||
*/
|
||||
public SystemBarConfig getConfig() {
|
||||
return mConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is tinting enabled for the system status bar?
|
||||
*
|
||||
* @return True if enabled, False otherwise.
|
||||
*/
|
||||
public boolean isStatusBarTintEnabled() {
|
||||
return mStatusBarTintEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is tinting enabled for the system navigation bar?
|
||||
*
|
||||
* @return True if enabled, False otherwise.
|
||||
*/
|
||||
public boolean isNavBarTintEnabled() {
|
||||
return mNavBarTintEnabled;
|
||||
}
|
||||
|
||||
private void setupStatusBarView(Context context, ViewGroup decorViewGroup) {
|
||||
mStatusBarTintView = new View(context);
|
||||
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getStatusBarHeight());
|
||||
params.gravity = Gravity.TOP;
|
||||
if (mNavBarAvailable && !mConfig.isNavigationAtBottom()) {
|
||||
params.rightMargin = mConfig.getNavigationBarWidth();
|
||||
}
|
||||
mStatusBarTintView.setLayoutParams(params);
|
||||
mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);
|
||||
mStatusBarTintView.setVisibility(View.GONE);
|
||||
decorViewGroup.addView(mStatusBarTintView);
|
||||
}
|
||||
|
||||
private void setupNavBarView(Context context, ViewGroup decorViewGroup) {
|
||||
mNavBarTintView = new View(context);
|
||||
LayoutParams params;
|
||||
if (mConfig.isNavigationAtBottom()) {
|
||||
params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getNavigationBarHeight());
|
||||
params.gravity = Gravity.BOTTOM;
|
||||
} else {
|
||||
params = new LayoutParams(mConfig.getNavigationBarWidth(), LayoutParams.MATCH_PARENT);
|
||||
params.gravity = Gravity.RIGHT;
|
||||
}
|
||||
mNavBarTintView.setLayoutParams(params);
|
||||
mNavBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);
|
||||
mNavBarTintView.setVisibility(View.GONE);
|
||||
decorViewGroup.addView(mNavBarTintView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class which describes system bar sizing and other characteristics for the current
|
||||
* device configuration.
|
||||
*
|
||||
*/
|
||||
public static class SystemBarConfig {
|
||||
|
||||
private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";
|
||||
private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height";
|
||||
private static final String NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME = "navigation_bar_height_landscape";
|
||||
private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width";
|
||||
private static final String SHOW_NAV_BAR_RES_NAME = "config_showNavigationBar";
|
||||
|
||||
private final boolean mTranslucentStatusBar;
|
||||
private final boolean mTranslucentNavBar;
|
||||
private final int mStatusBarHeight;
|
||||
private final int mActionBarHeight;
|
||||
private final boolean mHasNavigationBar;
|
||||
private final int mNavigationBarHeight;
|
||||
private final int mNavigationBarWidth;
|
||||
private final boolean mInPortrait;
|
||||
private final float mSmallestWidthDp;
|
||||
|
||||
private SystemBarConfig(Activity activity, boolean translucentStatusBar, boolean traslucentNavBar) {
|
||||
Resources res = activity.getResources();
|
||||
mInPortrait = (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
|
||||
mSmallestWidthDp = getSmallestWidthDp(activity);
|
||||
mStatusBarHeight = getInternalDimensionSize(res, STATUS_BAR_HEIGHT_RES_NAME);
|
||||
mActionBarHeight = getActionBarHeight(activity);
|
||||
mNavigationBarHeight = getNavigationBarHeight(activity);
|
||||
mNavigationBarWidth = getNavigationBarWidth(activity);
|
||||
mHasNavigationBar = (mNavigationBarHeight > 0);
|
||||
mTranslucentStatusBar = translucentStatusBar;
|
||||
mTranslucentNavBar = traslucentNavBar;
|
||||
}
|
||||
|
||||
@TargetApi(14)
|
||||
private int getActionBarHeight(Context context) {
|
||||
int result = 0;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
TypedValue tv = new TypedValue();
|
||||
context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);
|
||||
result = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@TargetApi(14)
|
||||
private int getNavigationBarHeight(Context context) {
|
||||
Resources res = context.getResources();
|
||||
int result = 0;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
if (hasNavBar(context)) {
|
||||
String key;
|
||||
if (mInPortrait) {
|
||||
key = NAV_BAR_HEIGHT_RES_NAME;
|
||||
} else {
|
||||
key = NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME;
|
||||
}
|
||||
return getInternalDimensionSize(res, key);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@TargetApi(14)
|
||||
private int getNavigationBarWidth(Context context) {
|
||||
Resources res = context.getResources();
|
||||
int result = 0;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
if (hasNavBar(context)) {
|
||||
return getInternalDimensionSize(res, NAV_BAR_WIDTH_RES_NAME);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@TargetApi(14)
|
||||
private boolean hasNavBar(Context context) {
|
||||
Resources res = context.getResources();
|
||||
int resourceId = res.getIdentifier(SHOW_NAV_BAR_RES_NAME, "bool", "android");
|
||||
if (resourceId != 0) {
|
||||
boolean hasNav = res.getBoolean(resourceId);
|
||||
// check override flag (see static block)
|
||||
if ("1".equals(sNavBarOverride)) {
|
||||
hasNav = false;
|
||||
} else if ("0".equals(sNavBarOverride)) {
|
||||
hasNav = true;
|
||||
}
|
||||
return hasNav;
|
||||
} else { // fallback
|
||||
return !ViewConfiguration.get(context).hasPermanentMenuKey();
|
||||
}
|
||||
}
|
||||
|
||||
private int getInternalDimensionSize(Resources res, String key) {
|
||||
int result = 0;
|
||||
int resourceId = res.getIdentifier(key, "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
result = res.getDimensionPixelSize(resourceId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private float getSmallestWidthDp(Activity activity) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
|
||||
} else {
|
||||
// TODO this is not correct, but we don't really care pre-kitkat
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
}
|
||||
float widthDp = metrics.widthPixels / metrics.density;
|
||||
float heightDp = metrics.heightPixels / metrics.density;
|
||||
return Math.min(widthDp, heightDp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should a navigation bar appear at the bottom of the screen in the current
|
||||
* device configuration? A navigation bar may appear on the right side of
|
||||
* the screen in certain configurations.
|
||||
*
|
||||
* @return True if navigation should appear at the bottom of the screen, False otherwise.
|
||||
*/
|
||||
public boolean isNavigationAtBottom() {
|
||||
return (mSmallestWidthDp >= 600 || mInPortrait);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the system status bar.
|
||||
*
|
||||
* @return The height of the status bar (in pixels).
|
||||
*/
|
||||
public int getStatusBarHeight() {
|
||||
return mStatusBarHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the action bar.
|
||||
*
|
||||
* @return The height of the action bar (in pixels).
|
||||
*/
|
||||
public int getActionBarHeight() {
|
||||
return mActionBarHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this device have a system navigation bar?
|
||||
*
|
||||
* @return True if this device uses soft key navigation, False otherwise.
|
||||
*/
|
||||
public boolean hasNavigtionBar() {
|
||||
return mHasNavigationBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the system navigation bar.
|
||||
*
|
||||
* @return The height of the navigation bar (in pixels). If the device does not have
|
||||
* soft navigation keys, this will always return 0.
|
||||
*/
|
||||
public int getNavigationBarHeight() {
|
||||
return mNavigationBarHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of the system navigation bar when it is placed vertically on the screen.
|
||||
*
|
||||
* @return The width of the navigation bar (in pixels). If the device does not have
|
||||
* soft navigation keys, this will always return 0.
|
||||
*/
|
||||
public int getNavigationBarWidth() {
|
||||
return mNavigationBarWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the layout inset for any system UI that appears at the top of the screen.
|
||||
*
|
||||
* @param withActionBar True to include the height of the action bar, False otherwise.
|
||||
* @return The layout inset (in pixels).
|
||||
*/
|
||||
public int getPixelInsetTop(boolean withActionBar) {
|
||||
return (mTranslucentStatusBar ? mStatusBarHeight : 0) + (withActionBar ? mActionBarHeight : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the layout inset for any system UI that appears at the bottom of the screen.
|
||||
*
|
||||
* @return The layout inset (in pixels).
|
||||
*/
|
||||
public int getPixelInsetBottom() {
|
||||
if (mTranslucentNavBar && isNavigationAtBottom()) {
|
||||
return mNavigationBarHeight;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the layout inset for any system UI that appears at the right of the screen.
|
||||
*
|
||||
* @return The layout inset (in pixels).
|
||||
*/
|
||||
public int getPixelInsetRight() {
|
||||
if (mTranslucentNavBar && !isNavigationAtBottom()) {
|
||||
return mNavigationBarWidth;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,203 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.manager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import zuo.biao.library.util.Log;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
|
||||
/**线程管理类
|
||||
* @author Lemon
|
||||
* @use ThreadManager.getInstance().runThread(...);
|
||||
* 在使用ThreadManager的Context被销毁前ThreadManager.getInstance().destroyThread(...);
|
||||
* 在应用退出前ThreadManager.getInstance().finish();
|
||||
*/
|
||||
public class ThreadManager {
|
||||
private static final String TAG = "ThreadManager";
|
||||
|
||||
|
||||
private Map<String, ThreadBean> threadMap;
|
||||
private ThreadManager() {
|
||||
threadMap = new HashMap<String, ThreadBean>();
|
||||
}
|
||||
|
||||
private static ThreadManager threadManager;
|
||||
public static synchronized ThreadManager getInstance() {
|
||||
if (threadManager == null) {
|
||||
threadManager = new ThreadManager();
|
||||
}
|
||||
|
||||
return threadManager;
|
||||
}
|
||||
|
||||
|
||||
/**运行线程
|
||||
* @param name
|
||||
* @param runnable
|
||||
* @return
|
||||
*/
|
||||
public Handler runThread(String name, Runnable runnable) {
|
||||
if (StringUtil.isNotEmpty(name, true) == false || runnable == null) {
|
||||
Log.e(TAG, "runThread StringUtil.isNotEmpty(name, true) == false || runnable == null >> return");
|
||||
return null;
|
||||
}
|
||||
name = StringUtil.getTrimedString(name);
|
||||
Log.d(TAG, "\n runThread name = " + name);
|
||||
|
||||
Handler handler = getHandler(name);
|
||||
if (handler != null) {
|
||||
Log.w(TAG, "handler != null >> destroyThread(name);");
|
||||
destroyThread(name);
|
||||
}
|
||||
|
||||
HandlerThread thread = new HandlerThread(name);
|
||||
thread.start();//创建一个HandlerThread并启动它
|
||||
handler = new Handler(thread.getLooper());//使用HandlerThread的looper对象创建Handler
|
||||
handler.post(runnable);//将线程post到Handler中
|
||||
|
||||
threadMap.put(name, new ThreadBean(name, thread, runnable, handler));
|
||||
|
||||
Log.d(TAG, "runThread added name = " + name + "; threadMap.size() = " + threadMap.size() + "\n");
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**获取线程Handler
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
private Handler getHandler(String name) {
|
||||
ThreadBean tb = getThread(name);
|
||||
return tb == null ? null : tb.getHandler();
|
||||
}
|
||||
|
||||
/**获取线程
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
private ThreadBean getThread(String name) {
|
||||
return name == null ? null : threadMap.get(name);
|
||||
}
|
||||
|
||||
|
||||
/**销毁线程
|
||||
* @param nameList
|
||||
* @return
|
||||
*/
|
||||
public void destroyThread(List<String> nameList) {
|
||||
if (nameList != null) {
|
||||
for (String name : nameList) {
|
||||
destroyThread(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**销毁线程
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public void destroyThread(String name) {
|
||||
destroyThread(getThread(name));
|
||||
}
|
||||
/**销毁线程
|
||||
* @param tb
|
||||
* @return
|
||||
*/
|
||||
private void destroyThread(ThreadBean tb) {
|
||||
if (tb == null) {
|
||||
Log.e(TAG, "destroyThread tb == null >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
destroyThread(tb.getHandler(), tb.getRunnable());
|
||||
if (tb.getName() != null) { // StringUtil.isNotEmpty(tb.getName(), true)) {
|
||||
threadMap.remove(tb.getName());
|
||||
}
|
||||
}
|
||||
/**销毁线程
|
||||
* @param handler
|
||||
* @param runnable
|
||||
* @return
|
||||
*/
|
||||
public void destroyThread(Handler handler, Runnable runnable) {
|
||||
if (handler == null || runnable == null) {
|
||||
Log.e(TAG, "destroyThread handler == null || runnable == null >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
handler.removeCallbacks(runnable);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "onDestroy try { handler.removeCallbacks(runnable);... >> catch : " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**结束ThreadManager所有进程
|
||||
*/
|
||||
public void finish() {
|
||||
threadManager = null;
|
||||
if (threadMap == null || threadMap.keySet() == null) {
|
||||
Log.d(TAG, "finish threadMap == null || threadMap.keySet() == null >> threadMap = null; >> return;");
|
||||
threadMap = null;
|
||||
return;
|
||||
}
|
||||
List<String> nameList = new ArrayList<String>(threadMap.keySet());//直接用Set在系统杀掉应用时崩溃
|
||||
if (nameList != null) {
|
||||
for (String name : nameList) {
|
||||
destroyThread(name);
|
||||
}
|
||||
}
|
||||
threadMap = null;
|
||||
Log.d(TAG, "\n finish finished \n");
|
||||
}
|
||||
|
||||
|
||||
/**线程类
|
||||
*/
|
||||
private static class ThreadBean {
|
||||
|
||||
private String name;
|
||||
@SuppressWarnings("unused")
|
||||
private HandlerThread thread;
|
||||
private Runnable runnable;
|
||||
private Handler handler;
|
||||
|
||||
public ThreadBean(String name, HandlerThread thread, Runnable runnable, Handler handler) {
|
||||
this.name = name;
|
||||
this.thread = thread;
|
||||
this.runnable = runnable;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Runnable getRunnable() {
|
||||
return runnable;
|
||||
}
|
||||
|
||||
public Handler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,207 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.manager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
/**时间刷新器
|
||||
* @author Lemon
|
||||
* @use TimeRefresher.getInstance().addTimeRefreshListener(...);
|
||||
* 在使用TimeRefresher的Context被销毁前TimeRefresher.getInstance().removeTimeRefreshListener(...);
|
||||
* 在应用退出前TimeRefresher.getInstance().finish();
|
||||
*/
|
||||
public class TimeRefresher {
|
||||
private static final String TAG = "TimeRefresher";
|
||||
|
||||
/**回调接口
|
||||
*/
|
||||
public interface OnTimeRefreshListener {
|
||||
|
||||
void onTimerStart();
|
||||
void onTimerRefresh();
|
||||
void onTimerStop();
|
||||
}
|
||||
|
||||
private Map<String, TimeRefresher.TimeHolder> refreshMap;
|
||||
private TimeRefresher() {
|
||||
refreshMap = new HashMap<String, TimeRefresher.TimeHolder>();
|
||||
}
|
||||
|
||||
private static TimeRefresher timeRefresher;
|
||||
public static TimeRefresher getInstance() {
|
||||
if (timeRefresher == null) {
|
||||
timeRefresher = new TimeRefresher();
|
||||
}
|
||||
|
||||
return timeRefresher;
|
||||
}
|
||||
|
||||
public boolean isContain(String tag) {
|
||||
return tag != null && refreshMap != null && refreshMap.containsKey(tag);
|
||||
}
|
||||
|
||||
public synchronized void addTimeRefreshListener(String tag, OnTimeRefreshListener listener) {
|
||||
addTimeRefreshListener(tag, 1000, listener);
|
||||
}
|
||||
public synchronized void addTimeRefreshListener(String tag, long duration, OnTimeRefreshListener listener) {
|
||||
if (duration > 0 && tag != null && listener != null) {
|
||||
Log.d(TAG, "\n addTimeRefreshListener duration > 0 && tag = " + tag + " && listener != null >>");
|
||||
if (refreshMap.containsKey(tag) && refreshMap.get(tag) != null) {
|
||||
refreshMap.get(tag).startTimer();
|
||||
Log.d(TAG, "refreshMap.containsKey(tag) && refreshMap.get(tag) != null >> refreshMap.get(tag).startTimer();");
|
||||
} else {
|
||||
refreshMap.put(tag, new TimeHolder(duration, listener));
|
||||
Log.d(TAG, "addTimeRefreshListener added tag = ");
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "addTimeRefreshListener refreshMap.size() = " + refreshMap.size() + "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tag
|
||||
*/
|
||||
public synchronized void startTimeRefreshListener(String tag) {
|
||||
TimeHolder holder = refreshMap.get("" + tag);
|
||||
if (holder != null) {
|
||||
holder.startTimer();
|
||||
Log.d(TAG, "startTimeRefreshListener started tag = " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tag
|
||||
*/
|
||||
public synchronized void stopTimeRefreshListener(String tag) {
|
||||
TimeHolder holder = refreshMap.get("" + tag);
|
||||
if (holder != null) {
|
||||
holder.stopTimer();
|
||||
Log.d(TAG, "stopTimeRefreshListener stopped tag = " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tag
|
||||
*/
|
||||
public synchronized void removeTimeRefreshListener(String tag) {
|
||||
TimeHolder holder = refreshMap.get("" + tag);
|
||||
if (holder != null) {
|
||||
holder.stopTimer();
|
||||
holder = null;
|
||||
}
|
||||
refreshMap.remove("" + tag);
|
||||
Log.d(TAG, "removeTimeRefreshListener removed tag = " + tag);
|
||||
}
|
||||
|
||||
/**完全结束Timer进程
|
||||
*/
|
||||
public void finish() {
|
||||
timeRefresher = null;
|
||||
if (refreshMap == null || refreshMap.size() <= 0) {
|
||||
Log.d(TAG, "finish refreshMap == null || refreshMap.size() <= 0 >> return;");
|
||||
return;
|
||||
}
|
||||
Set<String> tagSet = refreshMap.keySet();
|
||||
if (tagSet != null) {
|
||||
for (String tag : tagSet) {
|
||||
removeTimeRefreshListener(tag);
|
||||
}
|
||||
}
|
||||
refreshMap = null;
|
||||
Log.d(TAG, "\n finish finished \n");
|
||||
}
|
||||
|
||||
|
||||
/**计时器holder
|
||||
*/
|
||||
@SuppressLint("HandlerLeak")
|
||||
static class TimeHolder {
|
||||
|
||||
long duration = 1000;
|
||||
OnTimeRefreshListener listener;
|
||||
public TimeHolder(OnTimeRefreshListener listener) {
|
||||
this(1000, listener);
|
||||
}
|
||||
public TimeHolder(long duration, OnTimeRefreshListener listener) {
|
||||
this.duration = duration;
|
||||
this.listener = listener;
|
||||
startTimer();
|
||||
}
|
||||
|
||||
|
||||
Timer timer;
|
||||
TimerTask task;
|
||||
/**启动计时器
|
||||
*/
|
||||
public void startTimer() {
|
||||
if (listener == null) {
|
||||
Log.e(TAG, "startTimer listener == null >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
// Log.w(TAG, "startTimer<<<<<<<< " + TimeUtil.getTime(System.currentTimeMillis()));
|
||||
stopTimer();
|
||||
|
||||
listener.onTimerStart();
|
||||
if (timer == null) {
|
||||
timer = new Timer(true);
|
||||
}
|
||||
if (task == null) {
|
||||
task = new TimerTask(){
|
||||
public void run() {
|
||||
handler.sendEmptyMessage(0);
|
||||
}
|
||||
};
|
||||
}
|
||||
timer.schedule(task, 0, duration); //延时0ms后执行,1000ms执行一次
|
||||
// Log.w(TAG, "startTimer >>>>>>> " + TimeUtil.getTime(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
/**停止计时器
|
||||
*/
|
||||
public void stopTimer() {
|
||||
if (listener != null) {
|
||||
listener.onTimerStop();
|
||||
}
|
||||
// Log.w(TAG, "stopTimer<<<<<<<< " + TimeUtil.getTime(System.currentTimeMillis()));
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
timer = null;
|
||||
}
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
task = null;
|
||||
}
|
||||
// Log.w(TAG, "stopTimer>>>>>>> " + TimeUtil.getTime(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
final Handler handler = new Handler(){
|
||||
public void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
listener.onTimerRefresh();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
/**
|
||||
* 管理类所在包
|
||||
*/
|
||||
/**
|
||||
* @author Lemon
|
||||
* @use 通用使用方法:XXManager.getInstance().xxMethod(...)或new XXManager(...).xxMethod(...)
|
||||
*/
|
||||
package zuo.biao.library.manager;
|
@ -1,112 +0,0 @@
|
||||
package zuo.biao.library.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class City implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String province;
|
||||
private String city;
|
||||
// private String number;
|
||||
private String firstPY;
|
||||
private String allPY;
|
||||
private String allFristPY;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
private Double longitude;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
private Double latitude;
|
||||
|
||||
public City() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public City(String province, String city,Double lat, Double lon) {
|
||||
super();
|
||||
this.province = province;
|
||||
this.city = city;
|
||||
// this.number = number;
|
||||
// this.firstPY = firstPY;
|
||||
// this.allPY = allPY;
|
||||
// this.allFristPY = allFristPY;
|
||||
this.latitude = lat;
|
||||
this.longitude = lon;
|
||||
}
|
||||
|
||||
public String getProvince() {
|
||||
return province;
|
||||
}
|
||||
|
||||
public void setProvince(String province) {
|
||||
this.province = province;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
// public String getNumber() {
|
||||
// return number;
|
||||
// }
|
||||
//
|
||||
// public void setNumber(String number) {
|
||||
// this.number = number;
|
||||
// }
|
||||
|
||||
public String getFirstPY() {
|
||||
return firstPY;
|
||||
}
|
||||
|
||||
public void setFirstPY(String firstPY) {
|
||||
this.firstPY = firstPY;
|
||||
}
|
||||
|
||||
public String getAllPY() {
|
||||
return allPY;
|
||||
}
|
||||
|
||||
public void setAllPY(String allPY) {
|
||||
this.allPY = allPY;
|
||||
}
|
||||
|
||||
public String getAllFristPY() {
|
||||
return allFristPY;
|
||||
}
|
||||
|
||||
public void setAllFristPY(String allFristPY) {
|
||||
this.allFristPY = allFristPY;
|
||||
}
|
||||
|
||||
public Double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public void setLongitude(Double longitude) {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public Double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public void setLatitude(Double latitude) {
|
||||
this.latitude = latitude;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "City [province=" + province + ", city=" + city
|
||||
+ ", firstPY=" + firstPY + ", allPY=" + allPY
|
||||
+ ", allFristPY=" + allFristPY + "]";
|
||||
}
|
||||
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.model;
|
||||
|
||||
import zuo.biao.library.base.BaseModel;
|
||||
|
||||
/**自定义Entry
|
||||
* *java.util.Map.Entry是interface,new Entry(...)不好用,其它的Entry也不好用
|
||||
* @author Lemon
|
||||
* @param <K> key
|
||||
* @param <V> value
|
||||
* @use new Entry<K, V>(...)
|
||||
* @warn K,V都需要基本类型时不建议使用,判空麻烦,不如新建一个Model
|
||||
*/
|
||||
public class Entry<K, V> extends BaseModel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
public K key;
|
||||
public V value;
|
||||
|
||||
public Entry() {
|
||||
//default
|
||||
}
|
||||
public Entry(K key) {
|
||||
this(key, null);
|
||||
}
|
||||
public Entry(K key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
public void setKey(K key) {
|
||||
this.key = key;
|
||||
}
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
public void setValue(V value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isCorrect() {
|
||||
return key != null;
|
||||
}
|
||||
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.model;
|
||||
|
||||
/**GridPickerView初始化配置model
|
||||
*@author Lemon
|
||||
*@date 2015-7-23 上午12:54:01
|
||||
*/
|
||||
public class GridPickerConfig {
|
||||
|
||||
// private List<GridPickerItemBean> list;//list一般都会变 ,GridPickerView只允许一个list
|
||||
|
||||
private String tabSuffix;
|
||||
|
||||
private String selectedItemName;//可变
|
||||
private int selectedItemPostion;//可变
|
||||
|
||||
private int numColumns;//第一次设置后就固定不变
|
||||
private int maxShowRows;//第一次设置后就固定不变
|
||||
|
||||
// private int enableTextColor;
|
||||
// private int unableTextColor;
|
||||
//
|
||||
// private int enableBackgroundColor;
|
||||
// private int unableBackgroundColor;
|
||||
|
||||
public GridPickerConfig(String tabSuffix, String selectedItemName, int selectedItemPostion) {
|
||||
this(tabSuffix, selectedItemName, selectedItemPostion, 3, 5);
|
||||
}
|
||||
public GridPickerConfig(String tabSuffix, String selectedItemName, int selectedItemPostion, int numColumns, int maxShowRows) {
|
||||
this.tabSuffix = tabSuffix;
|
||||
this.selectedItemName = selectedItemName;
|
||||
this.selectedItemPostion = selectedItemPostion;
|
||||
|
||||
this.numColumns = numColumns;
|
||||
this.maxShowRows = maxShowRows;
|
||||
}
|
||||
|
||||
/**只允许通过这个方法修改数据
|
||||
* @param selectedItemName
|
||||
* @param selectedItemPostion
|
||||
* @return
|
||||
*/
|
||||
public final GridPickerConfig set(String selectedItemName, int selectedItemPostion) {
|
||||
return set(tabSuffix, selectedItemName, selectedItemPostion);
|
||||
}
|
||||
/**只允许通过这个方法修改数据
|
||||
* @param tabSuffix
|
||||
* @param selectedItemName
|
||||
* @param selectedItemPostion
|
||||
* @return
|
||||
*/
|
||||
public final GridPickerConfig set(String tabSuffix, String selectedItemName, int selectedItemPostion) {
|
||||
this.tabSuffix = tabSuffix;
|
||||
this.selectedItemName = selectedItemName;
|
||||
this.selectedItemPostion = selectedItemPostion;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**带后缀
|
||||
* @return
|
||||
*/
|
||||
public String getTabName() {
|
||||
return getSelectedItemName() + getTabSuffix();
|
||||
}
|
||||
|
||||
public String getTabSuffix() {
|
||||
return tabSuffix == null ? "" : tabSuffix;
|
||||
}
|
||||
|
||||
public String getSelectedItemName() {
|
||||
return selectedItemName == null ? "" : selectedItemName;
|
||||
}
|
||||
public int getSelectedItemPostion() {
|
||||
return selectedItemPostion;
|
||||
}
|
||||
|
||||
public int getNumColumns() {
|
||||
return numColumns;
|
||||
}
|
||||
|
||||
public int getMaxShowRows() {
|
||||
return maxShowRows;
|
||||
}
|
||||
|
||||
|
||||
// /**设置颜色
|
||||
// * @param enableTextColor
|
||||
// * @param unableTextColor
|
||||
// * @param enableBackgroundColor
|
||||
// * @param unableBackgroundColor
|
||||
// * @return
|
||||
// */
|
||||
// public final GridPickerConfig setColor(int enableTextColor, int unableTextColor, int enableBackgroundColor, int unableBackgroundColor) {
|
||||
// this.enableTextColor = enableTextColor;
|
||||
// this.unableTextColor = unableTextColor;
|
||||
// this.enableBackgroundColor = enableBackgroundColor;
|
||||
// this.unableBackgroundColor = unableBackgroundColor;
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public int getEnableTextColor() {
|
||||
// return enableTextColor;
|
||||
// }
|
||||
// public GridPickerConfig setEnableTextColor(int enableTextColor) {
|
||||
// this.enableTextColor = enableTextColor;
|
||||
// return this;
|
||||
// }
|
||||
// public int getUnableTextColor() {
|
||||
// return unableTextColor;
|
||||
// }
|
||||
// public GridPickerConfig setUnableTextColor(int unableTextColor) {
|
||||
// this.unableTextColor = unableTextColor;
|
||||
// return this;
|
||||
// }
|
||||
// public int getEnableBackgroundColor() {
|
||||
// return enableBackgroundColor;
|
||||
// }
|
||||
// public GridPickerConfig setEnableBackgroundColor(int enableBackgroundColor) {
|
||||
// this.enableBackgroundColor = enableBackgroundColor;
|
||||
// return this;
|
||||
// }
|
||||
// public int getUnableBackgroundColor() {
|
||||
// return unableBackgroundColor;
|
||||
// }
|
||||
// public GridPickerConfig setUnableBackgroundColor(int unableBackgroundColor) {
|
||||
// this.unableBackgroundColor = unableBackgroundColor;
|
||||
// return this;
|
||||
// }
|
||||
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.model;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
/**菜单类
|
||||
* @author Lemon
|
||||
*/
|
||||
public class Menu {
|
||||
|
||||
private String name;
|
||||
private int imageRes;
|
||||
private int operationType;
|
||||
private Intent operationIntent;
|
||||
private int intentCode;
|
||||
|
||||
public Menu() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
public Menu(String name) {
|
||||
this();
|
||||
this.name = name;
|
||||
}
|
||||
public Menu(String name, int imageRes) {
|
||||
this(name);
|
||||
this.imageRes = imageRes;
|
||||
}
|
||||
public Menu(String name, int imageRes, int intentCode) {
|
||||
this(name, imageRes);
|
||||
this.intentCode = intentCode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public int getImageRes() {
|
||||
return imageRes;
|
||||
}
|
||||
public void setImageRes(int imageRes) {
|
||||
this.imageRes = imageRes;
|
||||
}
|
||||
public int getOperationType() {
|
||||
return operationType;
|
||||
}
|
||||
public void setOperationType(int operationType) {
|
||||
this.operationType = operationType;
|
||||
}
|
||||
public Intent getOperationIntent() {
|
||||
return operationIntent;
|
||||
}
|
||||
public void setOperationIntent(Intent operationIntent) {
|
||||
this.operationIntent = operationIntent;
|
||||
}
|
||||
public int getIntentCode() {
|
||||
return intentCode;
|
||||
}
|
||||
public void setIntentCode(int intentCode) {
|
||||
this.intentCode = intentCode;
|
||||
}
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.model;
|
||||
|
||||
/**Http请求参数类
|
||||
* @author Lemon
|
||||
*/
|
||||
public class Parameter extends Entry<String, Object> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Parameter(String key, Object value) {
|
||||
super(key, value);
|
||||
}
|
||||
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
/**
|
||||
* 模型类所在包
|
||||
*/
|
||||
/**
|
||||
* @author Lemon
|
||||
* @use 通用使用方法:
|
||||
* XXBean xxb = new XXBean(...);
|
||||
* xxb.setXX(...);
|
||||
* xxb.getXX();
|
||||
*/
|
||||
package zuo.biao.library.model;
|
@ -1,142 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**通用对话框类
|
||||
* @author Lemon
|
||||
* @use new AlertDialog(...).show();
|
||||
*/
|
||||
public class AlertDialog extends Dialog implements android.view.View.OnClickListener {
|
||||
// private static final String TAG = "AlertDialog";
|
||||
|
||||
/**
|
||||
* 自定义Dialog监听器
|
||||
*/
|
||||
public interface OnDialogButtonClickListener {
|
||||
|
||||
/**点击按钮事件的回调方法
|
||||
* @param requestCode 传入的用于区分某种情况下的showDialog
|
||||
* @param isPositive
|
||||
*/
|
||||
void onDialogButtonClick(int requestCode, boolean isPositive);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Context context;
|
||||
private String title;
|
||||
private String message;
|
||||
private String strPositive;
|
||||
private String strNegative;
|
||||
private boolean showNegativeButton = true;
|
||||
private int requestCode;
|
||||
private OnDialogButtonClickListener listener;
|
||||
|
||||
/**
|
||||
* 带监听器参数的构造函数
|
||||
*/
|
||||
public AlertDialog(Context context, String title, String message, boolean showNegativeButton,
|
||||
int requestCode, OnDialogButtonClickListener listener) {
|
||||
super(context, R.style.MyDialog);
|
||||
|
||||
this.context = context;
|
||||
this.title = title;
|
||||
this.message = message;
|
||||
this.showNegativeButton = showNegativeButton;
|
||||
this.requestCode = requestCode;
|
||||
this.listener = listener;
|
||||
}
|
||||
public AlertDialog(Context context, String title, String message, boolean showNegativeButton,
|
||||
String strPositive, int requestCode, OnDialogButtonClickListener listener) {
|
||||
super(context, R.style.MyDialog);
|
||||
|
||||
this.context = context;
|
||||
this.title = title;
|
||||
this.message = message;
|
||||
this.showNegativeButton = showNegativeButton;
|
||||
this.strPositive = strPositive;
|
||||
this.requestCode = requestCode;
|
||||
this.listener = listener;
|
||||
}
|
||||
public AlertDialog(Context context, String title, String message,
|
||||
String strPositive, String strNegative, int requestCode, OnDialogButtonClickListener listener) {
|
||||
super(context, R.style.MyDialog);
|
||||
|
||||
this.context = context;
|
||||
this.title = title;
|
||||
this.message = message;
|
||||
this.strPositive = strPositive;
|
||||
this.strNegative = strNegative;
|
||||
this.requestCode = requestCode;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
private TextView tvTitle;
|
||||
private TextView tvMessage;
|
||||
private Button btnPositive;
|
||||
private Button btnNegative;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.alert_dialog);
|
||||
setCanceledOnTouchOutside(true);
|
||||
|
||||
tvTitle = (TextView) findViewById(R.id.tvAlertDialogTitle);
|
||||
tvMessage = (TextView) findViewById(R.id.tvAlertDialogMessage);
|
||||
btnPositive = (Button) findViewById(R.id.btnAlertDialogPositive);
|
||||
btnNegative = (Button) findViewById(R.id.btnAlertDialogNegative);
|
||||
|
||||
tvTitle.setVisibility(StringUtil.isNotEmpty(title, true) ? View.VISIBLE : View.GONE);
|
||||
tvTitle.setText("" + StringUtil.getCurrentString());
|
||||
|
||||
if (StringUtil.isNotEmpty(strPositive, true)) {
|
||||
btnPositive.setText(StringUtil.getCurrentString());
|
||||
}
|
||||
btnPositive.setOnClickListener(this);
|
||||
|
||||
if (showNegativeButton) {
|
||||
if (StringUtil.isNotEmpty(strNegative, true)) {
|
||||
btnNegative.setText(StringUtil.getCurrentString());
|
||||
}
|
||||
btnNegative.setOnClickListener(this);
|
||||
} else {
|
||||
btnNegative.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
tvMessage.setText(StringUtil.getTrimedString(message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
if (v.getId() == R.id.btnAlertDialogPositive) {
|
||||
listener.onDialogButtonClick(requestCode, true);
|
||||
} else if (v.getId() == R.id.btnAlertDialogNegative) {
|
||||
listener.onDialogButtonClick(requestCode, false);
|
||||
}
|
||||
|
||||
dismiss();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,179 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.base.BaseView;
|
||||
import zuo.biao.library.model.Menu;
|
||||
import zuo.biao.library.util.CommonUtil;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**自定义嵌入式菜单View
|
||||
* @author Lemon
|
||||
* @use
|
||||
* <br> BottomMenuView bottomMenuView = new BottomMenuView(context, resources, toBottomMenuWindowRequestCode);
|
||||
* <br> bottomMenuView.bindView(menuList);
|
||||
* <br> bottomMenuView.setOnMenuItemClickListener(onBottomMenuItemClickListener);
|
||||
* <br> *具体参考.UserActivity
|
||||
*/
|
||||
public class BottomMenuView extends BaseView<List<Menu>> {
|
||||
private static final String TAG = "BottomMenuView";
|
||||
|
||||
public interface OnBottomMenuItemClickListener{
|
||||
void onBottomMenuItemClick(int intentCode);
|
||||
}
|
||||
|
||||
private OnBottomMenuItemClickListener onBottomMenuItemClickListener;
|
||||
public void setOnMenuItemClickListener(OnBottomMenuItemClickListener l) {
|
||||
onBottomMenuItemClickListener = l;
|
||||
}
|
||||
|
||||
|
||||
private int toBottomMenuWindowRequestCode;
|
||||
public BottomMenuView(Activity context, Resources resources, int toBottomMenuWindowRequestCode) {
|
||||
super(context, resources);
|
||||
this.toBottomMenuWindowRequestCode = toBottomMenuWindowRequestCode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private LayoutInflater inflater;
|
||||
|
||||
public LinearLayout llBottomMenuViewMainItemContainer;
|
||||
/**获取View
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
public View createView(LayoutInflater inflater) {
|
||||
this.inflater = inflater;
|
||||
convertView = inflater.inflate(R.layout.bottom_menu_view, null);
|
||||
|
||||
llBottomMenuViewMainItemContainer = (LinearLayout)
|
||||
convertView.findViewById(R.id.llBottomMenuViewMainItemContainer);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Menu> getData() {
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<Menu> list;//传进来的数据
|
||||
private ArrayList<String> moreMenuNameList;
|
||||
private ArrayList<Integer> moreMenuIntentCodeList;
|
||||
@Override
|
||||
public void bindView(final List<Menu> menuList){
|
||||
if (menuList == null || menuList.isEmpty()) {
|
||||
Log.e(TAG, "bindView menuList == null || menuList.isEmpty() >> return;");
|
||||
return;
|
||||
}
|
||||
this.list = menuList;
|
||||
|
||||
llBottomMenuViewMainItemContainer.removeAllViews();
|
||||
final int mainItemCount = list.size() > 4 ? 3 : list.size();//不包括 更多 按钮
|
||||
Menu fsb;
|
||||
for (int i = 0; i < mainItemCount; i++) {
|
||||
fsb = list.get(i);
|
||||
if (fsb.getImageRes() > 0) {
|
||||
addItem(false, i, fsb);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//菜单区域外的背景及监听不好做,还是点击更多弹出BottomMenuWindow好
|
||||
if (list.size() > 4) {
|
||||
addItem(true, -1, null);
|
||||
|
||||
//弹出底部菜单
|
||||
moreMenuNameList = new ArrayList<String>();
|
||||
moreMenuIntentCodeList = new ArrayList<Integer>();
|
||||
Menu moreFsb;
|
||||
for (int i = 3; i < list.size(); i++) {
|
||||
moreFsb = list.get(i);
|
||||
if (moreFsb != null) {
|
||||
moreMenuNameList.add(moreFsb.getName());
|
||||
moreMenuIntentCodeList.add(moreFsb.getIntentCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**添加带图标的主要按钮
|
||||
* @param position
|
||||
* @param fsb
|
||||
*/
|
||||
@SuppressLint("InflateParams")
|
||||
private void addItem(final boolean isMoreButton, final int position, final Menu fsb) {
|
||||
if (isMoreButton == false) {
|
||||
if (position < 0 || fsb == null || StringUtil.isNotEmpty(fsb.getName(), true) == false
|
||||
|| fsb.getImageRes() <= 0) {
|
||||
Log.e(TAG, "addItem isMoreButton == false >> position < 0 || fsb == null " +
|
||||
"|| StringUtil.isNotEmpty(fsb.getName(), true) == false " +
|
||||
"|| fsb.getImageRes() <= 0 >> return;");
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
LinearLayout ll = (LinearLayout) inflater.inflate(R.layout.icon_name_item, null);
|
||||
ImageView iv = (ImageView) ll.findViewById(R.id.ivIconNameIcon);
|
||||
TextView tv = (TextView) ll.findViewById(R.id.tvIconNameName);
|
||||
try {
|
||||
iv.setImageResource(isMoreButton ? R.drawable.up2_light : fsb.getImageRes());
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "addItem try {" +
|
||||
" iv.setImageResource(fsb.getImageRes()); " + e.getMessage() + ">> return;");
|
||||
return;
|
||||
}
|
||||
tv.setText(isMoreButton ? "更多" : "" + fsb.getName());
|
||||
|
||||
ll.setPadding(
|
||||
(int) getDimension(R.dimen.common_item_left_tv_padding),
|
||||
0,
|
||||
(int) getDimension(R.dimen.common_item_right_img_padding_right),
|
||||
0);
|
||||
ll.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (isMoreButton) {
|
||||
CommonUtil.toActivity(context, BottomMenuWindow.createIntent(context
|
||||
, moreMenuNameList, moreMenuIntentCodeList)
|
||||
.putExtra(BottomMenuWindow.INTENT_TITLE, "更多"), toBottomMenuWindowRequestCode, false);
|
||||
} else {
|
||||
onBottomMenuItemClickListener.onBottomMenuItemClick(fsb.getIntentCode());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
llBottomMenuViewMainItemContainer.addView(ll, position);
|
||||
}
|
||||
|
||||
}
|
@ -1,282 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.base.BaseBottomWindow;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
/**通用底部弹出菜单
|
||||
* @author Lemon
|
||||
* @use
|
||||
* <br> toActivity或startActivityForResult (BottomMenuWindow.createIntent(...), requestCode);
|
||||
* <br> 然后在onActivityResult方法内
|
||||
* <br> data.getIntExtra(BottomMenuWindow.RESULT_ITEM_ID); 可得到点击的 position
|
||||
* <br> 或
|
||||
* <br> data.getIntExtra(BottomMenuWindow.RESULT_INTENT_CODE); 可得到点击的 intentCode
|
||||
*/
|
||||
public class BottomMenuWindow extends BaseBottomWindow implements OnItemClickListener {
|
||||
private static final String TAG = "BottomMenuWindow";
|
||||
|
||||
//启动方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
/**启动BottomMenuWindow的Intent
|
||||
* @param context
|
||||
* @param names
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, String[] names) {
|
||||
return createIntent(context, names, new ArrayList<Integer>());
|
||||
}
|
||||
|
||||
/**启动BottomMenuWindow的Intent
|
||||
* @param context
|
||||
* @param nameList
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, ArrayList<String> nameList) {
|
||||
return createIntent(context, nameList, null);
|
||||
}
|
||||
|
||||
/**启动BottomMenuWindow的Intent
|
||||
* @param context
|
||||
* @param names
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, String[] names, int[] ids) {
|
||||
return new Intent(context, BottomMenuWindow.class).
|
||||
putExtra(INTENT_ITEMS, names).
|
||||
putExtra(INTENT_ITEM_IDS, ids);
|
||||
}
|
||||
|
||||
/**启动BottomMenuWindow的Intent
|
||||
* @param context
|
||||
* @param names
|
||||
* @param idList
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, String[] names, ArrayList<Integer> idList) {
|
||||
return new Intent(context, BottomMenuWindow.class).
|
||||
putExtra(INTENT_ITEMS, names).
|
||||
putExtra(INTENT_ITEM_IDS, idList);
|
||||
}
|
||||
|
||||
/**启动BottomMenuWindow的Intent
|
||||
* @param context
|
||||
* @param nameList
|
||||
* @param idList
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context,
|
||||
ArrayList<String> nameList, ArrayList<Integer> idList) {
|
||||
return new Intent(context, BottomMenuWindow.class).
|
||||
putStringArrayListExtra(INTENT_ITEMS, nameList).
|
||||
putIntegerArrayListExtra(INTENT_ITEM_IDS, idList);
|
||||
}
|
||||
|
||||
//启动方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
@Override
|
||||
public Activity getActivity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.bottom_menu_window);
|
||||
|
||||
//功能归类分区方法,必须调用<<<<<<<<<<
|
||||
initView();
|
||||
initData();
|
||||
initEvent();
|
||||
//功能归类分区方法,必须调用>>>>>>>>>>
|
||||
|
||||
}
|
||||
|
||||
|
||||
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private ListView lvBottomMenu;
|
||||
@Override
|
||||
public void initView() {//必须调用
|
||||
super.initView();
|
||||
|
||||
lvBottomMenu = (ListView) findViewById(R.id.lvBottomMenu);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private String title;
|
||||
private ArrayList<String> nameList = null;
|
||||
private ArrayList<Integer> idList = null;
|
||||
|
||||
private ArrayAdapter<String> adapter;
|
||||
@Override
|
||||
public void initData() {//必须调用
|
||||
super.initData();
|
||||
|
||||
intent = getIntent();
|
||||
|
||||
title = intent.getStringExtra(INTENT_TITLE);
|
||||
if (StringUtil.isNotEmpty(title, true)) {
|
||||
tvBaseTitle.setVisibility(View.VISIBLE);
|
||||
tvBaseTitle.setText(StringUtil.getCurrentString());
|
||||
} else {
|
||||
tvBaseTitle.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
int[] ids = intent.getIntArrayExtra(INTENT_ITEM_IDS);
|
||||
if (ids == null || ids.length <= 0) {
|
||||
idList = intent.getIntegerArrayListExtra(INTENT_ITEM_IDS);
|
||||
} else {
|
||||
idList = new ArrayList<Integer>();
|
||||
for (int id : ids) {
|
||||
idList.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
String[] menuItems = intent.getStringArrayExtra(INTENT_ITEMS);
|
||||
if (menuItems == null || menuItems.length <= 0) {
|
||||
nameList = intent.getStringArrayListExtra(INTENT_ITEMS);
|
||||
} else {
|
||||
nameList = new ArrayList<String>(Arrays.asList(menuItems));
|
||||
}
|
||||
if (nameList == null || nameList.size() <= 0) {
|
||||
Log.e(TAG, "init nameList == null || nameList.size() <= 0 >> finish();return;");
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
adapter = new ArrayAdapter<String>(this, R.layout.bottom_menu_item, R.id.tvBottomMenuItem, nameList);
|
||||
lvBottomMenu.setAdapter(adapter);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {//必须调用
|
||||
super.initEvent();
|
||||
|
||||
lvBottomMenu.setOnItemClickListener(this);
|
||||
|
||||
vBaseBottomWindowRoot.setOnTouchListener(new OnTouchListener() {
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//系统自带监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
|
||||
//类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
intent = new Intent()
|
||||
.putExtra(RESULT_TITLE, StringUtil.getTrimedString(tvBaseTitle))
|
||||
.putExtra(RESULT_ITEM_ID, position);
|
||||
if (idList != null && idList.size() > position) {
|
||||
intent.putExtra(RESULT_ITEM_ID, idList.get(position));
|
||||
}
|
||||
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setResult() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
//类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//系统自带监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
//内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,297 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.base.BaseActivity;
|
||||
import zuo.biao.library.util.CommonUtil;
|
||||
import zuo.biao.library.util.DataKeeper;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
|
||||
/**通用获取裁剪单张照片Activity
|
||||
* @author Lemon
|
||||
* @use
|
||||
* <br> toActivity或startActivityForResult (CutPictureActivity.createIntent(...), requestCode);
|
||||
* <br> 然后在onActivityResult方法内
|
||||
* <br> data.getStringExtra(CutPictureActivity.RESULT_PICTURE_PATH); 可得到图片存储路径
|
||||
*/
|
||||
public class CutPictureActivity extends BaseActivity {
|
||||
private static final String TAG = "CutPictureActivity";
|
||||
|
||||
//启动方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
public static final String INTENT_ORIGINAL_PICTURE_PATH = "INTENT_ORIGINAL_PICTURE_PATH";
|
||||
public static final String INTENT_CUTTED_PICTURE_PATH = "INTENT_CUTTED_PICTURE_PATH";
|
||||
public static final String INTENT_CUTTED_PICTURE_NAME = "INTENT_CUTTED_PICTURE_NAME";
|
||||
|
||||
public static final String INTENT_CUT_WIDTH = "INTENT_CUT_WIDTH";
|
||||
public static final String INTENT_CUT_HEIGHT = "INTENT_CUT_HEIGHT";
|
||||
|
||||
/**启动这个Activity的Intent
|
||||
* @param context
|
||||
* @param originalPath
|
||||
* @param cuttedPath
|
||||
* @param cuttedName
|
||||
* @param cuttedSize
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, String originalPath
|
||||
, String cuttedPath, String cuttedName, int cuttedSize) {
|
||||
return createIntent(context, originalPath, cuttedPath, cuttedName, cuttedSize, cuttedSize);
|
||||
}
|
||||
/**启动这个Activity的Intent
|
||||
* @param context
|
||||
* @param originalPath
|
||||
* @param cuttedPath
|
||||
* @param cuttedName
|
||||
* @param cuttedWidth
|
||||
* @param cuttedHeight
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, String originalPath
|
||||
, String cuttedPath, String cuttedName, int cuttedWidth, int cuttedHeight) {
|
||||
Intent intent = new Intent(context, CutPictureActivity.class);
|
||||
intent.putExtra(INTENT_ORIGINAL_PICTURE_PATH, originalPath);
|
||||
intent.putExtra(INTENT_CUTTED_PICTURE_PATH, cuttedPath);
|
||||
intent.putExtra(INTENT_CUTTED_PICTURE_NAME, cuttedName);
|
||||
intent.putExtra(INTENT_CUT_WIDTH, cuttedWidth);
|
||||
intent.putExtra(INTENT_CUT_HEIGHT, cuttedHeight);
|
||||
return intent;
|
||||
}
|
||||
|
||||
//启动方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
@Override
|
||||
public Activity getActivity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
private String originalPicturePath;
|
||||
private String cuttedPicturePath;
|
||||
private String cuttedPictureName;
|
||||
private int cuttedWidth;
|
||||
private int cuttedHeight;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
intent = getIntent();
|
||||
|
||||
originalPicturePath = intent.getStringExtra(INTENT_ORIGINAL_PICTURE_PATH);
|
||||
cuttedWidth = intent.getIntExtra(INTENT_CUT_WIDTH, 0);
|
||||
cuttedHeight = intent.getIntExtra(INTENT_CUT_HEIGHT, 0);
|
||||
if (cuttedWidth <= 0) {
|
||||
cuttedWidth = cuttedHeight;
|
||||
}
|
||||
if (cuttedHeight <= 0) {
|
||||
cuttedHeight = cuttedWidth;
|
||||
}
|
||||
|
||||
if (StringUtil.isNotEmpty(originalPicturePath, true) == false || cuttedWidth <= 0) {
|
||||
Log.e(TAG, "onCreate StringUtil.isNotEmpty(originalPicturePath, true)" +
|
||||
" == false || cuttedWidth <= 0 >> finish(); return;");
|
||||
showShortToast("图片不存在,请先选择图片");
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
//功能归类分区方法,必须调用<<<<<<<<<<
|
||||
initData();
|
||||
initView();
|
||||
initEvent();
|
||||
//功能归类分区方法,必须调用>>>>>>>>>>
|
||||
|
||||
}
|
||||
|
||||
|
||||
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initView() {//必须调用
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**照片裁剪
|
||||
* @param path
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
public void startPhotoZoom(String path, int width, int height) {
|
||||
startPhotoZoom(Uri.fromFile(new File(path)), width, height);
|
||||
}
|
||||
/**照片裁剪
|
||||
* @param fileUri
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
public void startPhotoZoom(Uri fileUri, int width, int height) {
|
||||
|
||||
intent = new Intent("com.android.camera.action.CROP");
|
||||
intent.setDataAndType(fileUri, "image/*");
|
||||
// aspectX aspectY 是宽高的比例
|
||||
intent.putExtra("aspectX", 1);
|
||||
intent.putExtra("aspectY", 1);
|
||||
|
||||
// outputX,outputY 是剪裁图片的宽高
|
||||
intent.putExtra("outputX", width);
|
||||
intent.putExtra("outputY", height);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
File outputImage = new File(DataKeeper.imagePath, "output_image" + System.currentTimeMillis() + ".jpg");
|
||||
cuttedPicturePath = outputImage.getAbsolutePath();
|
||||
intent.putExtra("scale", true);
|
||||
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outputImage));
|
||||
} else {
|
||||
intent.putExtra("crop", "true");// crop为true是设置在开启的intent中设置显示的view可以剪裁
|
||||
intent.putExtra("return-data", true);
|
||||
}
|
||||
Log.i(TAG, "startPhotoZoom fileUri = "+ fileUri);
|
||||
toActivity(intent, REQUEST_CUT_PHOTO);
|
||||
}
|
||||
|
||||
|
||||
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void initData() {//必须调用
|
||||
|
||||
startPhotoZoom(originalPicturePath, cuttedWidth, cuttedHeight);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {//必须调用
|
||||
|
||||
}
|
||||
|
||||
//系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
//类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
public static final int REQUEST_CODE_CAMERA = 18;
|
||||
public static final int REQUEST_CODE_LOCAL = 19;
|
||||
public static final int REQUEST_CUT_PHOTO = 20;
|
||||
|
||||
public static final String RESULT_PICTURE_PATH = "RESULT_PICTURE_PATH";
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode == RESULT_OK) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_CUT_PHOTO: //发送本地图片
|
||||
if (data != null) {
|
||||
if (Build.VERSION.SDK_INT < 23 || new File(cuttedPicturePath).exists() == false) {
|
||||
Bundle bundle = data.getExtras();
|
||||
if (bundle != null) {
|
||||
Bitmap photo = bundle.getParcelable("data");
|
||||
//photo.
|
||||
if (photo != null) {
|
||||
//照片的路径
|
||||
setCuttedPicturePath();
|
||||
cuttedPicturePath = CommonUtil.savePhotoToSDCard(cuttedPicturePath, cuttedPictureName, "jpg", photo);
|
||||
}
|
||||
}
|
||||
}
|
||||
setResult(RESULT_OK, new Intent().putExtra(RESULT_PICTURE_PATH, cuttedPicturePath));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
private String setCuttedPicturePath() {
|
||||
//oringlePicturePath 不对
|
||||
cuttedPicturePath = intent.getStringExtra(INTENT_CUTTED_PICTURE_PATH);
|
||||
if (StringUtil.isFilePath(cuttedPicturePath) == false) {
|
||||
cuttedPicturePath = DataKeeper.fileRootPath + DataKeeper.imagePath;
|
||||
}
|
||||
cuttedPictureName = intent.getStringExtra(INTENT_CUTTED_PICTURE_NAME);
|
||||
if (StringUtil.isFilePath(cuttedPictureName) == false) {
|
||||
cuttedPictureName = "photo" + System.currentTimeMillis();
|
||||
}
|
||||
return cuttedPicturePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
exitAnim = enterAnim = R.anim.null_anim;
|
||||
super.finish();
|
||||
}
|
||||
|
||||
//类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
//内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,414 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.base.BaseViewBottomWindow;
|
||||
import zuo.biao.library.model.Entry;
|
||||
import zuo.biao.library.model.GridPickerConfig;
|
||||
import zuo.biao.library.ui.GridPickerView.OnTabClickListener;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import zuo.biao.library.util.TimeUtil;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**日期选择窗口
|
||||
* @author Lemon
|
||||
* @use
|
||||
* <br> toActivity或startActivityForResult (DatePickerWindow.createIntent(...), requestCode);
|
||||
* <br> 然后在onActivityResult方法内
|
||||
* <br> data.getLongExtra(DatePickerWindow.RESULT_TIME_IN_MILLIS); 可得到选中的日期
|
||||
* @warn 和android系统SDK内一样,month从0开始
|
||||
*/
|
||||
public class DatePickerWindow extends BaseViewBottomWindow<List<Entry<Integer, String>>, GridPickerView> {
|
||||
private static final String TAG = "DatePickerWindow";
|
||||
|
||||
//启动方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
public static final String INTENT_MIN_DATE = "INTENT_MIN_DATE";
|
||||
public static final String INTENT_MAX_DATE = "INTENT_MAX_DATE";
|
||||
public static final String INTENT_DEFAULT_DATE = "INTENT_DEFAULT_DATE";
|
||||
|
||||
public static final String RESULT_DATE = "RESULT_DATE";
|
||||
public static final String RESULT_TIME_IN_MILLIS = "RESULT_TIME_IN_MILLIS";
|
||||
public static final String RESULT_DATE_DETAIL_LIST = "RESULT_DATE_DETAIL_LIST";
|
||||
|
||||
/**启动这个Activity的Intent
|
||||
* @param context
|
||||
* @param limitYearMonthDay
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, int[] limitYearMonthDay) {
|
||||
return createIntent(context, limitYearMonthDay, null);
|
||||
}
|
||||
/**启动这个Activity的Intent
|
||||
* @param context
|
||||
* @param limitYearMonthDay
|
||||
* @param defaultYearMonthDay
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, int[] limitYearMonthDay, int[] defaultYearMonthDay) {
|
||||
int[] selectedDate = TimeUtil.getDateDetail(System.currentTimeMillis());
|
||||
int[] minYearMonthDay = null;
|
||||
int[] maxYearMonthDay = null;
|
||||
if (TimeUtil.fomerIsBigger(limitYearMonthDay, selectedDate)) {
|
||||
minYearMonthDay = selectedDate;
|
||||
maxYearMonthDay = limitYearMonthDay;
|
||||
} else {
|
||||
minYearMonthDay = limitYearMonthDay;
|
||||
maxYearMonthDay = selectedDate;
|
||||
}
|
||||
return createIntent(context, minYearMonthDay, maxYearMonthDay, defaultYearMonthDay);
|
||||
}
|
||||
/**启动这个Activity的Intent
|
||||
* @param context
|
||||
* @param minYearMonthDay
|
||||
* @param maxYearMonthDay
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, int[] minYearMonthDay, int[] maxYearMonthDay, int[] defaultYearMonthDay) {
|
||||
return new Intent(context, DatePickerWindow.class).
|
||||
putExtra(INTENT_MIN_DATE, minYearMonthDay).
|
||||
putExtra(INTENT_MAX_DATE, maxYearMonthDay).
|
||||
putExtra(INTENT_DEFAULT_DATE, defaultYearMonthDay);
|
||||
}
|
||||
|
||||
//启动方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
@Override
|
||||
public Activity getActivity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
//功能归类分区方法,必须调用<<<<<<<<<<
|
||||
initView();
|
||||
initData();
|
||||
initEvent();
|
||||
//功能归类分区方法,必须调用>>>>>>>>>>
|
||||
|
||||
}
|
||||
|
||||
|
||||
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
@Override
|
||||
public void initView() {//必须调用
|
||||
super.initView();
|
||||
|
||||
}
|
||||
|
||||
private List<Entry<Integer, String>> list;
|
||||
private void setPickerView(final int tabPosition) {
|
||||
runThread(TAG + "setPickerView", new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
final ArrayList<Integer> selectedItemList = new ArrayList<Integer>();
|
||||
for (GridPickerConfig gpcb : configList) {
|
||||
selectedItemList.add(0 + Integer.valueOf(StringUtil.getNumber(gpcb.getSelectedItemName())));
|
||||
}
|
||||
|
||||
list = getList(tabPosition, selectedItemList);
|
||||
|
||||
runUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
containerView.bindView(tabPosition, list);
|
||||
|
||||
//防止选中非闰年2月29日
|
||||
if (tabPosition < 2) {
|
||||
ArrayList<String> selectedList = containerView.getSelectedItemList();
|
||||
if (selectedList != null && selectedList.size() >= 3) {
|
||||
|
||||
if (TimeUtil.isLeapYear(0 + Integer.valueOf(
|
||||
StringUtil.getNumber(selectedList.get(0)))) == false) {
|
||||
|
||||
if ("2".equals(StringUtil.getNumber(selectedList.get(1)))
|
||||
&& "29".equals(StringUtil.getNumber(selectedList.get(2)))) {
|
||||
|
||||
onItemSelectedListener.onItemSelected(
|
||||
null, null, containerView.getCurrentSelectedItemPosition(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
// private long minDate;
|
||||
// private long maxDate;
|
||||
|
||||
private int[] minDateDetails;
|
||||
private int[] maxDateDetails;
|
||||
private int[] defaultDateDetails;
|
||||
|
||||
private ArrayList<GridPickerConfig> configList;
|
||||
@Override
|
||||
public void initData() {//必须调用
|
||||
super.initData();
|
||||
|
||||
intent = getIntent();
|
||||
|
||||
// minDate = getIntent().getLongExtra(INTENT_MIN_DATE, 0);
|
||||
// maxDate = getIntent().getLongExtra(INTENT_MAX_DATE, 0);
|
||||
// if (minDate >= maxDate) {
|
||||
// Log.e(TAG, "initData minDate >= maxDate >> finish(); return; ");
|
||||
// finish();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
|
||||
// int[] minDateDetails = TimeUtil.getDateDetail(minDate);
|
||||
// int[] maxDateDetails = TimeUtil.getDateDetail(maxDate);
|
||||
minDateDetails = intent.getIntArrayExtra(INTENT_MIN_DATE);
|
||||
maxDateDetails = intent.getIntArrayExtra(INTENT_MAX_DATE);
|
||||
defaultDateDetails = intent.getIntArrayExtra(INTENT_DEFAULT_DATE);
|
||||
|
||||
if (minDateDetails == null || minDateDetails.length <= 0) {
|
||||
minDateDetails = new int[]{1970, 1, 1};
|
||||
}
|
||||
if (maxDateDetails == null || maxDateDetails.length <= 0) {
|
||||
maxDateDetails = new int[]{2020, 11, 31};
|
||||
}
|
||||
if (minDateDetails == null || minDateDetails.length <= 0
|
||||
|| maxDateDetails == null || minDateDetails.length != maxDateDetails.length) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
if (defaultDateDetails == null || defaultDateDetails.length < 3) {
|
||||
defaultDateDetails = TimeUtil.getDateDetail(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
||||
runThread(TAG + "initData", new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final ArrayList<Integer> selectedItemList = new ArrayList<Integer>();
|
||||
selectedItemList.add(defaultDateDetails[0]);
|
||||
selectedItemList.add(defaultDateDetails[1]);
|
||||
selectedItemList.add(defaultDateDetails[2]);
|
||||
|
||||
list = getList(selectedItemList.size() - 1, selectedItemList);
|
||||
|
||||
runUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
containerView.init(configList, list);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("ResourceAsColor")
|
||||
private synchronized List<Entry<Integer, String>> getList(int tabPosition, ArrayList<Integer> selectedItemList) {
|
||||
int level = TimeUtil.LEVEL_YEAR + tabPosition;
|
||||
if (selectedItemList == null || selectedItemList.size() != 3 || TimeUtil.isContainLevel(level) == false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
list = new ArrayList<Entry<Integer, String>>();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(selectedItemList.get(0), selectedItemList.get(1) - 1, 1);
|
||||
switch (level) {
|
||||
case TimeUtil.LEVEL_YEAR:
|
||||
for (int i = 0; i < maxDateDetails[0] - minDateDetails[0]; i++) {
|
||||
list.add(new Entry<Integer, String>(GridPickerAdapter.TYPE_CONTNET_ENABLE, String.valueOf(i + 1 + minDateDetails[0])));
|
||||
}
|
||||
break;
|
||||
case TimeUtil.LEVEL_MONTH:
|
||||
for (int i = 0; i < 12; i++) {
|
||||
list.add(new Entry<Integer, String>(GridPickerAdapter.TYPE_CONTNET_ENABLE, String.valueOf(i + 1)));
|
||||
}
|
||||
break;
|
||||
case TimeUtil.LEVEL_DAY:
|
||||
for (int i = calendar.get(Calendar.DAY_OF_WEEK) - 1; i < 7; i++) {
|
||||
list.add(new Entry<Integer, String>(GridPickerAdapter.TYPE_TITLE, TimeUtil.Day.getDayNameOfWeek(i)));
|
||||
}
|
||||
for (int i = 0; i < calendar.get(Calendar.DAY_OF_WEEK) - 1; i++) {
|
||||
list.add(new Entry<Integer, String>(GridPickerAdapter.TYPE_TITLE, TimeUtil.Day.getDayNameOfWeek(i)));
|
||||
}
|
||||
for (int i = 0; i < calendar.getActualMaximum(Calendar.DATE); i++) {
|
||||
list.add(new Entry<Integer, String>(GridPickerAdapter.TYPE_CONTNET_ENABLE, String.valueOf(i + 1)));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (configList == null || configList.size() < 3) {
|
||||
configList = new ArrayList<GridPickerConfig>();
|
||||
|
||||
configList.add(new GridPickerConfig(TimeUtil.NAME_YEAR, "" + selectedItemList.get(0)
|
||||
, selectedItemList.get(0) - 1 - minDateDetails[0], 5, 4));
|
||||
configList.add(new GridPickerConfig(TimeUtil.NAME_MONTH, "" + selectedItemList.get(1)
|
||||
, selectedItemList.get(1) - 1, 4, 3));
|
||||
configList.add(new GridPickerConfig(TimeUtil.NAME_DAY, "" + selectedItemList.get(2)
|
||||
, selectedItemList.get(2) - 1 + 7, 7, 6));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getTitleName() {
|
||||
return "选择日期";
|
||||
}
|
||||
@Override
|
||||
public String getReturnName() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String getForwardName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GridPickerView createView() {
|
||||
return new GridPickerView(context, getResources());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setResult() {
|
||||
intent = new Intent();
|
||||
|
||||
List<String> list = containerView.getSelectedItemList();
|
||||
if (list != null && list.size() >= 3) {
|
||||
ArrayList<Integer> detailList = new ArrayList<Integer>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
detailList.add(0 + Integer.valueOf(StringUtil.getNumber(list.get(i))));
|
||||
}
|
||||
detailList.set(1, detailList.get(1) - 1);
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(detailList.get(0), detailList.get(1), detailList.get(2));
|
||||
intent.putExtra(RESULT_TIME_IN_MILLIS, calendar.getTimeInMillis());
|
||||
intent.putIntegerArrayListExtra(RESULT_DATE_DETAIL_LIST, detailList);
|
||||
}
|
||||
|
||||
setResult(RESULT_OK, intent);
|
||||
}
|
||||
|
||||
|
||||
//Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void initEvent() {//必须调用
|
||||
super.initEvent();
|
||||
|
||||
containerView.setOnTabClickListener(onTabClickListener);
|
||||
containerView.setOnItemSelectedListener(onItemSelectedListener);
|
||||
}
|
||||
|
||||
|
||||
private OnTabClickListener onTabClickListener = new OnTabClickListener() {
|
||||
|
||||
@Override
|
||||
public void onTabClick(int tabPosition, TextView tvTab) {
|
||||
setPickerView(tabPosition);
|
||||
}
|
||||
};
|
||||
|
||||
private OnItemSelectedListener onItemSelectedListener = new OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, final int position, long id) {
|
||||
containerView.doOnItemSelected(containerView.getCurrentTabPosition()
|
||||
, position, containerView.getCurrentSelectedItemName());
|
||||
int tabPosition = containerView.getCurrentTabPosition() + 1;
|
||||
setPickerView(tabPosition);
|
||||
}
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) { }
|
||||
};
|
||||
|
||||
//系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
//类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
|
||||
//类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
//内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,460 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.base.BaseActivity;
|
||||
import zuo.biao.library.interfaces.OnBottomDragListener;
|
||||
import zuo.biao.library.util.EditTextUtil;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Handler.Callback;
|
||||
import android.os.Message;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AbsListView.OnScrollListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**通用编辑个人资料文本界面
|
||||
* @author Lemon
|
||||
* @use
|
||||
* <br> toActivity或startActivityForResult (EditTextInfoActivity.createIntent(...), requestCode);
|
||||
* <br> 然后在onActivityResult方法内
|
||||
* <br> data.getStringExtra(EditTextInfoActivity.RESULT_EDIT_TEXT_INFO); 可得到输入框内容
|
||||
*/
|
||||
public class EditTextInfoActivity extends BaseActivity implements OnBottomDragListener {
|
||||
public static final String TAG = "EditTextInfoActivity";
|
||||
|
||||
//启动方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
public static final String RESULT_TYPE = "RESULT_TYPE";
|
||||
public static final String RESULT_KEY = "RESULT_KEY";
|
||||
public static final String RESULT_VALUE = "RESULT_VALUE";
|
||||
public static final String RESULT_URL = "RESULT_URL";
|
||||
public static final String RESULT_ID = "RESULT_ID";
|
||||
public static final String RESULT_IMAGE_URL = "RESULT_IMAGE_URL";
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, String key, String value) {
|
||||
return createIntent(context, 0, key, value);
|
||||
}
|
||||
/**
|
||||
* @param context
|
||||
* @param type
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, int type, String key, String value) {
|
||||
return new Intent(context, EditTextInfoActivity.class).
|
||||
putExtra(INTENT_TYPE, type).
|
||||
putExtra(INTENT_KEY, key).
|
||||
putExtra(INTENT_VALUE, value);
|
||||
}
|
||||
|
||||
//启动方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Activity getActivity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.edit_text_info_activity, this);//传this是为了全局滑动返回
|
||||
|
||||
//必须调用<<<<<<<<<<<
|
||||
initView();
|
||||
initData();
|
||||
initEvent();
|
||||
//必须调用>>>>>>>>>>
|
||||
|
||||
}
|
||||
|
||||
|
||||
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private EditText etEditTextInfo;
|
||||
private View ivEditTextInfoClear;
|
||||
private TextView tvEditTextInfoRemind;
|
||||
private ListView lvEditTextInfo;
|
||||
// private XListView lvEditTextInfo;
|
||||
@Override
|
||||
public void initView() {//必须调用
|
||||
|
||||
etEditTextInfo = (EditText) findViewById(R.id.etEditTextInfo);
|
||||
ivEditTextInfoClear = findViewById(R.id.ivEditTextInfoClear);
|
||||
tvEditTextInfoRemind = (TextView) findViewById(R.id.tvEditTextInfoRemind);
|
||||
|
||||
lvEditTextInfo = (ListView) findViewById(R.id.lvEditTextInfo);
|
||||
}
|
||||
|
||||
private ArrayAdapter<String> adapter;
|
||||
/**显示列表内容
|
||||
* @author author
|
||||
* @param list
|
||||
*/
|
||||
private void setList(List<String> list) {
|
||||
if (hasList == false || list == null || list.size() <= 0) {
|
||||
Log.i(TAG, "setList list == null || list.size() <= 0 >> adapter = null;lvEditTextInfo.setAdapter(null); return;");
|
||||
adapter = null;
|
||||
lvEditTextInfo.setAdapter(null);
|
||||
return;
|
||||
}
|
||||
|
||||
adapter = new ArrayAdapter<String>(context, R.layout.list_item, R.id.tvListItem, list);
|
||||
lvEditTextInfo.setAdapter(adapter);
|
||||
// if (hasUrl) {
|
||||
// }
|
||||
lvEditTextInfo.smoothScrollBy(60, 200);
|
||||
}
|
||||
|
||||
|
||||
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
public static final int TYPE_NICK = EditTextInfoWindow.TYPE_NICK;
|
||||
public static final int TYPE_NAME = EditTextInfoWindow.TYPE_NAME;
|
||||
|
||||
public static final int TYPE_PHONE = EditTextInfoWindow.TYPE_PHONE;
|
||||
public static final int TYPE_WEBSITE = EditTextInfoWindow.TYPE_WEBSITE;
|
||||
public static final int TYPE_EMAIL = EditTextInfoWindow.TYPE_EMAIL;
|
||||
public static final int TYPE_FAX = EditTextInfoWindow.TYPE_FAX;
|
||||
|
||||
public static final int TYPE_USUALADDRESS = EditTextInfoWindow.TYPE_USUALADDRESS;
|
||||
public static final int TYPE_MAILADDRESS = EditTextInfoWindow.TYPE_MAILADDRESS;
|
||||
public static final int TYPE_SCHOOL = EditTextInfoWindow.TYPE_SCHOOL;
|
||||
public static final int TYPE_COMPANY = EditTextInfoWindow.TYPE_COMPANY;
|
||||
|
||||
public static final int TYPE_PROFESSION = EditTextInfoWindow.TYPE_PROFESSION;
|
||||
public static final int TYPE_NOTE = EditTextInfoWindow.TYPE_NOTE;
|
||||
// public static final int TYPE_OTHER = EditTextInfoWindow.TYPE_OTHER;
|
||||
|
||||
public static final String INTENT_TYPE = EditTextInfoWindow.INTENT_TYPE;
|
||||
public static final String INTENT_KEY = EditTextInfoWindow.INTENT_KEY;
|
||||
public static final String INTENT_VALUE = EditTextInfoWindow.INTENT_VALUE;
|
||||
|
||||
private int intentType = 0;
|
||||
private int maxEms = 30;
|
||||
private boolean hasList = false;
|
||||
private boolean hasUrl = false;
|
||||
|
||||
private ArrayList<String> list;
|
||||
@Override
|
||||
public void initData() {//必须调用
|
||||
intent = getIntent();
|
||||
|
||||
intentType = intent.getIntExtra(INTENT_TYPE, 0);
|
||||
if (StringUtil.isNotEmpty(intent.getStringExtra(INTENT_KEY), true)) {
|
||||
tvBaseTitle.setText(StringUtil.getCurrentString());
|
||||
}
|
||||
etEditTextInfo.setSingleLine(intentType != TYPE_NOTE);
|
||||
|
||||
switch (intentType) {
|
||||
case TYPE_NICK:
|
||||
maxEms = 20;
|
||||
break;
|
||||
case TYPE_PHONE:
|
||||
etEditTextInfo.setInputType(InputType.TYPE_CLASS_PHONE);
|
||||
maxEms = 11;
|
||||
break;
|
||||
case TYPE_EMAIL:
|
||||
etEditTextInfo.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
||||
maxEms = 60;
|
||||
break;
|
||||
case TYPE_WEBSITE:
|
||||
etEditTextInfo.setInputType(InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT);
|
||||
maxEms = 200;
|
||||
break;
|
||||
case TYPE_MAILADDRESS:
|
||||
maxEms = 60;
|
||||
break;
|
||||
case TYPE_PROFESSION:
|
||||
tvEditTextInfoRemind.setText("所属行业");
|
||||
maxEms = 15;
|
||||
case TYPE_NOTE:
|
||||
maxEms = 100;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
etEditTextInfo.setMaxEms(maxEms);
|
||||
tvEditTextInfoRemind.setText("限" + maxEms/2 + "个字(或" + maxEms + "个字符)");
|
||||
|
||||
|
||||
getList(intentType);
|
||||
}
|
||||
|
||||
private int requestSize = 20;
|
||||
/**获取列表
|
||||
* @author lemon
|
||||
* @param listType
|
||||
* @return
|
||||
*/
|
||||
protected void getList(final int listType) {
|
||||
if (hasList == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
list = new ArrayList<String>();
|
||||
runThread(TAG + "getList", new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(TAG, "getList listType = " + listType);
|
||||
if (listType == TYPE_PROFESSION) {
|
||||
list = new ArrayList<String>(Arrays.asList(context.getResources().getStringArray(R.array.profesions)));
|
||||
}
|
||||
|
||||
runUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
dismissProgressDialog();
|
||||
if (hasList) {
|
||||
setList(list);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void saveAndExit() {
|
||||
String editedValue = StringUtil.getTrimedString(etEditTextInfo);
|
||||
if (editedValue.equals("" + getIntent().getStringExtra(INTENT_VALUE))) {
|
||||
showShortToast("内容没有改变哦~");
|
||||
} else {
|
||||
intent = new Intent();
|
||||
intent.putExtra(RESULT_TYPE, getIntent().getIntExtra(INTENT_TYPE, -1));
|
||||
// intent.putExtra(RESULT_TYPE, StringUtil.getTrimedString(etEditTextInfo));
|
||||
// intent.putExtra(RESULT_KEY, StringUtil.getTrimedString(etEditTextInfo));
|
||||
intent.putExtra(RESULT_VALUE, editedValue);
|
||||
setResult(RESULT_OK, intent);
|
||||
|
||||
exitAnim = R.anim.left_push_out;
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
//Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private String inputedString;
|
||||
|
||||
private static final long SEARCH_DELAY_TIME = 240;
|
||||
private Handler searchHandler;
|
||||
@Override
|
||||
public void initEvent() {//必须调用
|
||||
|
||||
searchHandler = new Handler(new Callback() {
|
||||
@Override
|
||||
public boolean handleMessage(Message msg) {
|
||||
if (msg == null) {
|
||||
Log.e(TAG, "searchHandler handleMessage (msg == null >> return false;");
|
||||
return false;
|
||||
}
|
||||
|
||||
Log.i(TAG, "inputedString = " + inputedString + "msg.obj = " + msg.obj);
|
||||
if(inputedString != null){
|
||||
if (inputedString.equals(msg.obj)) {
|
||||
getList(intentType);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
etEditTextInfo.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
inputedString = StringUtil.getTrimedString(s);
|
||||
if (StringUtil.isNotEmpty(inputedString, true) == false) {
|
||||
ivEditTextInfoClear.setVisibility(View.GONE);
|
||||
} else {
|
||||
ivEditTextInfoClear.setVisibility(View.VISIBLE);
|
||||
if (hasUrl == true) {
|
||||
Message msg = new Message();
|
||||
msg.obj = inputedString;
|
||||
searchHandler.sendMessageDelayed(msg , SEARCH_DELAY_TIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
});
|
||||
ivEditTextInfoClear.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
etEditTextInfo.setText("");
|
||||
}
|
||||
});
|
||||
|
||||
etEditTextInfo.setText(StringUtil.getTrimedString(getIntent().getStringExtra(INTENT_VALUE)));
|
||||
etEditTextInfo.setSelection(StringUtil.getLength(etEditTextInfo, true));
|
||||
|
||||
if (hasList == true) {
|
||||
EditTextUtil.hideKeyboard(context, etEditTextInfo);
|
||||
|
||||
if (hasUrl) {
|
||||
lvEditTextInfo.setOnScrollListener(new OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
||||
}
|
||||
@Override
|
||||
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
||||
if (adapter != null && lvEditTextInfo.getLastVisiblePosition() >= adapter.getCount() - 1) {
|
||||
requestSize += 20;
|
||||
Log.i(TAG, "initEvent lvEditTextInfo.setOnScrollListener( >> onScroll getList(intentType);requestSize = " + requestSize);
|
||||
getList(intentType);
|
||||
}
|
||||
}
|
||||
});
|
||||
// } else {
|
||||
}
|
||||
lvEditTextInfo.setOnItemClickListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
// if (hasUrl) {
|
||||
// position -= lvEditTextInfo.getHeaderViewsCount();
|
||||
// }
|
||||
if (position < adapter.getCount()) {
|
||||
etEditTextInfo.setText("" + adapter.getItem(position));
|
||||
if (hasUrl) {
|
||||
intent = new Intent();
|
||||
intent.putExtra(RESULT_TYPE, getIntent().getIntExtra(INTENT_TYPE, -1));
|
||||
intent.putExtra(RESULT_KEY, getIntent().getStringExtra(INTENT_KEY));
|
||||
intent.putExtra(RESULT_VALUE, adapter.getItem(position));
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
saveAndExit();
|
||||
}
|
||||
}
|
||||
});
|
||||
lvEditTextInfo.setOnTouchListener(new View.OnTouchListener() {
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
EditTextUtil.hideKeyboard(context, etEditTextInfo);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragBottom(boolean rightToLeft) {
|
||||
if (rightToLeft) {
|
||||
saveAndExit();
|
||||
return;
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onForwardClick(View v) {
|
||||
if (hasUrl == false) {
|
||||
onDragBottom(true);
|
||||
} else {
|
||||
Message msg = new Message();
|
||||
msg.obj = inputedString;
|
||||
searchHandler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
//系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
EditTextUtil.hideKeyboard(context, etEditTextInfo);
|
||||
}
|
||||
|
||||
//类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
//类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
//内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,380 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.base.BaseBottomWindow;
|
||||
import zuo.biao.library.util.CommonUtil;
|
||||
import zuo.biao.library.util.ContactUtil;
|
||||
import zuo.biao.library.util.EditTextUtil;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**通用编辑个人资料文本界面
|
||||
* @author Lemon
|
||||
* @use
|
||||
* <br> toActivity或startActivityForResult (EditTextInfoWindow.createIntent(...), requestCode);
|
||||
* <br> 然后在onActivityResult方法内
|
||||
* <br> data.getStringExtra(EditTextInfoWindow.RESULT_EDIT_TEXT_INFO); 可得到输入框内容
|
||||
*/
|
||||
public class EditTextInfoWindow extends BaseBottomWindow implements OnClickListener {
|
||||
// private static final String TAG = "EditTextInfoWindow";
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, String key, String value) {
|
||||
return createIntent(context, key, value, "zuo.biao.library");
|
||||
}
|
||||
/**
|
||||
* @param context
|
||||
* @param key
|
||||
* @param value
|
||||
* @param packageName
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, String key, String value, String packageName) {
|
||||
return createIntent(context, 0, key, value, packageName);
|
||||
}
|
||||
/**
|
||||
* @param context
|
||||
* @param type
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, int type, String key, String value) {
|
||||
return createIntent(context, type, key, value, "zuo.biao.library");
|
||||
}
|
||||
/**
|
||||
* @param context
|
||||
* @param type
|
||||
* @param key
|
||||
* @param value
|
||||
* @param packageName type == TYPE_MAILADDRESS || type == TYPE_USUALADDRESS时必须不为空
|
||||
* @return
|
||||
*/
|
||||
public static Intent createIntent(Context context, int type, String key, String value, String packageName) {
|
||||
return new Intent(context, EditTextInfoWindow.class).
|
||||
putExtra(INTENT_TYPE, type).
|
||||
putExtra(INTENT_KEY, key).
|
||||
putExtra(INTENT_VALUE, value).
|
||||
putExtra(INTENT_PACKAGE_NAME, packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Activity getActivity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.edit_text_info_window);
|
||||
|
||||
//必须调用<<<<<<<<<<<
|
||||
initView();
|
||||
initData();
|
||||
initEvent();
|
||||
//必须调用>>>>>>>>>>
|
||||
|
||||
}
|
||||
|
||||
|
||||
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private TextView tvEditTextInfoPlace;
|
||||
private EditText etEditTextInfo;
|
||||
private View ivEditTextInfoClear;
|
||||
private TextView tvEditTextInfoRemind;
|
||||
@Override
|
||||
public void initView() {//必须调用
|
||||
super.initView();
|
||||
|
||||
tvEditTextInfoPlace = (TextView) findViewById(R.id.tvEditTextInfoPlace);
|
||||
tvEditTextInfoPlace.setVisibility(View.GONE);
|
||||
|
||||
etEditTextInfo = (EditText) findViewById(R.id.etEditTextInfo);
|
||||
ivEditTextInfoClear = findViewById(R.id.ivEditTextInfoClear);
|
||||
tvEditTextInfoRemind = (TextView) findViewById(R.id.tvEditTextInfoRemind);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
public static final String INTENT_PACKAGE_NAME = "INTENT_PACKAGE_NAME";
|
||||
|
||||
public static final int TYPE_NICK = ContactUtil.TYPE_NICK;
|
||||
public static final int TYPE_NAME = ContactUtil.TYPE_NAME;
|
||||
|
||||
public static final int TYPE_PHONE = ContactUtil.TYPE_PHONE;
|
||||
public static final int TYPE_WEBSITE = ContactUtil.TYPE_WEBSITE;
|
||||
public static final int TYPE_EMAIL = ContactUtil.TYPE_EMAIL;
|
||||
public static final int TYPE_FAX = ContactUtil.TYPE_FAX;
|
||||
|
||||
public static final int TYPE_USUALADDRESS = ContactUtil.TYPE_USUALADDRESS;
|
||||
public static final int TYPE_MAILADDRESS = ContactUtil.TYPE_MAILADDRESS;
|
||||
public static final int TYPE_SCHOOL = ContactUtil.TYPE_SCHOOL;
|
||||
public static final int TYPE_COMPANY = ContactUtil.TYPE_COMPANY;
|
||||
|
||||
public static final int TYPE_PROFESSION = ContactUtil.TYPE_PROFESSION;
|
||||
public static final int TYPE_NOTE = ContactUtil.TYPE_NOTE;
|
||||
// public static final int TYPE_OTHER = ContactUtil.TYPE_OTHER;
|
||||
|
||||
public static final int TYPE_NUMBER = 21;
|
||||
public static final int TYPE_DECIMAL = 22;
|
||||
|
||||
public static final String INTENT_TYPE = "INTENT_TYPE";
|
||||
public static final String INTENT_KEY = "INTENT_KEY";
|
||||
public static final String INTENT_VALUE = "INTENT_VALUE";
|
||||
|
||||
private String packageName;
|
||||
private int intentType = 0;
|
||||
private int maxEms = 30;
|
||||
@Override
|
||||
public void initData() {//必须调用
|
||||
super.initData();
|
||||
|
||||
intent = getIntent();
|
||||
packageName = intent.getStringExtra(INTENT_PACKAGE_NAME);
|
||||
|
||||
intentType = intent.getIntExtra(INTENT_TYPE, 0);
|
||||
if (StringUtil.isNotEmpty(intent.getStringExtra(INTENT_KEY), true)) {
|
||||
tvBaseTitle.setText(StringUtil.getCurrentString());
|
||||
}
|
||||
etEditTextInfo.setSingleLine(intentType != TYPE_NOTE);
|
||||
|
||||
switch (intentType) {
|
||||
case TYPE_NICK:
|
||||
maxEms = 20;
|
||||
break;
|
||||
case TYPE_PHONE:
|
||||
maxEms = 11;
|
||||
etEditTextInfo.setInputType(InputType.TYPE_CLASS_PHONE);
|
||||
break;
|
||||
case TYPE_EMAIL:
|
||||
maxEms = 60;
|
||||
etEditTextInfo.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
||||
break;
|
||||
case TYPE_WEBSITE:
|
||||
maxEms = 200;
|
||||
etEditTextInfo.setInputType(InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT);
|
||||
break;
|
||||
case TYPE_MAILADDRESS:
|
||||
maxEms = 60;
|
||||
break;
|
||||
case TYPE_PROFESSION:
|
||||
tvEditTextInfoRemind.setText("所属行业");
|
||||
maxEms = 15;
|
||||
case TYPE_NOTE:
|
||||
maxEms = 100;
|
||||
break;
|
||||
case TYPE_NUMBER:
|
||||
maxEms = 10;
|
||||
etEditTextInfo.setInputType(InputType.TYPE_NUMBER_VARIATION_NORMAL);
|
||||
break;
|
||||
case TYPE_DECIMAL:
|
||||
maxEms = 20;
|
||||
etEditTextInfo.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
etEditTextInfo.setMaxEms(maxEms);
|
||||
tvEditTextInfoRemind.setText("限" + maxEms/2 + "个字(或" + maxEms + "个字符)");
|
||||
|
||||
if (intentType == TYPE_MAILADDRESS || intentType == TYPE_USUALADDRESS) {
|
||||
tvEditTextInfoPlace.setVisibility(View.VISIBLE);
|
||||
CommonUtil.toActivity(context, PlacePickerWindow.createIntent(
|
||||
context, packageName, 2), REQUEST_TO_PLACE_PICKER, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setResult() {
|
||||
intent = new Intent();
|
||||
intent.putExtra(RESULT_TYPE, getIntent().getIntExtra(INTENT_TYPE, -1));
|
||||
intent.putExtra(RESULT_KEY, getIntent().getStringExtra(INTENT_KEY));
|
||||
intent.putExtra(RESULT_VALUE, editedValue);
|
||||
setResult(RESULT_OK, intent);
|
||||
}
|
||||
|
||||
|
||||
//Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private String inputedString;
|
||||
@Override
|
||||
public void initEvent() {//必须调用
|
||||
super.initEvent();
|
||||
|
||||
tvEditTextInfoPlace.setOnClickListener(this);
|
||||
|
||||
etEditTextInfo.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
inputedString = StringUtil.getTrimedString(s);
|
||||
if (StringUtil.isNotEmpty(inputedString, true) == false) {
|
||||
ivEditTextInfoClear.setVisibility(View.GONE);
|
||||
} else {
|
||||
ivEditTextInfoClear.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
});
|
||||
ivEditTextInfoClear.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
etEditTextInfo.setText("");
|
||||
}
|
||||
});
|
||||
|
||||
etEditTextInfo.setText(StringUtil.getTrimedString(getIntent().getStringExtra(INTENT_VALUE)));
|
||||
etEditTextInfo.setSelection(StringUtil.getLength(etEditTextInfo, true));
|
||||
|
||||
}
|
||||
|
||||
private String editedValue;
|
||||
@Override
|
||||
public void onForwardClick(View v) {
|
||||
editedValue = StringUtil.getTrimedString(tvEditTextInfoPlace) + StringUtil.getTrimedString(etEditTextInfo);
|
||||
if (editedValue.equals("" + getIntent().getStringExtra(INTENT_VALUE))) {
|
||||
CommonUtil.showShortToast(context, "内容没有改变哦~");
|
||||
return;
|
||||
}
|
||||
super.onForwardClick(v);
|
||||
}
|
||||
|
||||
//系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
public static final String RESULT_TYPE = "RESULT_TYPE";
|
||||
public static final String RESULT_KEY = "RESULT_KEY";
|
||||
public static final String RESULT_VALUE = "RESULT_VALUE";
|
||||
public static final String RESULT_URL = "RESULT_URL";
|
||||
public static final String RESULT_ID = "RESULT_ID";
|
||||
public static final String RESULT_IMAGE_URL = "RESULT_IMAGE_URL";
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.getId() == R.id.tvEditTextInfoPlace) {
|
||||
CommonUtil.toActivity(context, PlacePickerWindow.createIntent(
|
||||
context, packageName, 2), REQUEST_TO_PLACE_PICKER, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
EditTextUtil.hideKeyboard(context, etEditTextInfo);
|
||||
}
|
||||
|
||||
|
||||
public static final int REQUEST_TO_PLACE_PICKER = 11;
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode != RESULT_OK) {
|
||||
return;
|
||||
}
|
||||
switch (requestCode) {
|
||||
case REQUEST_TO_PLACE_PICKER:
|
||||
List<String> list = data == null ? null : data.getStringArrayListExtra(PlacePickerWindow.RESULT_PLACE_LIST);
|
||||
if (list == null || list.size() < 2) {
|
||||
CommonUtil.showShortToast(context, "请先选择地址哦~");
|
||||
CommonUtil.toActivity(context, PlacePickerWindow.createIntent(
|
||||
context, packageName, 2), REQUEST_TO_PLACE_PICKER, false);
|
||||
return;
|
||||
}
|
||||
String place = "";
|
||||
for (String s : list) {
|
||||
place += s;
|
||||
}
|
||||
tvEditTextInfoPlace.setText(place);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
//系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
|
||||
|
||||
//内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,283 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**通用密码、手机号、验证码输入框输入字符判断及错误提示 类
|
||||
* @author Lemon
|
||||
* @use EditTextManager.xxxMethod(...);
|
||||
*/
|
||||
public class EditTextManager {
|
||||
private static final String TAG = "EditTextManager";
|
||||
|
||||
|
||||
//显示/隐藏输入法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
private static InputMethodManager imm;
|
||||
|
||||
/**隐藏输入法
|
||||
* @param context
|
||||
* @param toGetWindowTokenView
|
||||
*/
|
||||
public static void hideKeyboard(Context context, View toGetWindowTokenView){
|
||||
showKeyboard(context, null, toGetWindowTokenView, false);
|
||||
}
|
||||
/**显示输入法
|
||||
* @param context
|
||||
* @param et
|
||||
*/
|
||||
public static void showKeyboard(Context context, EditText et){
|
||||
showKeyboard(context, et, true);
|
||||
}
|
||||
/**显示/隐藏输入法
|
||||
* @param context
|
||||
* @param et
|
||||
* @param show
|
||||
*/
|
||||
public static void showKeyboard(Context context, EditText et, boolean show){
|
||||
showKeyboard(context, et, null, show);
|
||||
}
|
||||
/**显示输入法
|
||||
* @param context
|
||||
* @param et
|
||||
* @param toGetWindowTokenView(为null时toGetWindowTokenView = et) 包含et的父View,键盘根据toGetWindowTokenView的位置来弹出/隐藏
|
||||
*/
|
||||
public static void showKeyboard(Context context, EditText et, View toGetWindowTokenView) {
|
||||
showKeyboard(context, et, toGetWindowTokenView, true);
|
||||
}
|
||||
/**显示/隐藏输入法
|
||||
* @param context
|
||||
* @param et
|
||||
* @param toGetWindowTokenView(为null时toGetWindowTokenView = et) 包含et的父View,键盘根据toGetWindowTokenView的位置来弹出/隐藏
|
||||
* @param show
|
||||
*/
|
||||
public static void showKeyboard(Context context, EditText et, View toGetWindowTokenView, boolean show){
|
||||
if (context == null) {
|
||||
Log.e(TAG, "showKeyboard context == null >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);//imm必须与context唯一对应
|
||||
if (toGetWindowTokenView == null) {
|
||||
Log.w(TAG, "showKeyboard toGetWindowTokenView == null");
|
||||
toGetWindowTokenView = et;
|
||||
}
|
||||
if (toGetWindowTokenView == null) {
|
||||
Log.e(TAG, "showKeyboard toGetWindowTokenView == null && et == null >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
if (show == false) {
|
||||
imm.hideSoftInputFromWindow(toGetWindowTokenView.getWindowToken(), 0);
|
||||
if (et != null) {
|
||||
et.clearFocus();
|
||||
}
|
||||
} else {
|
||||
if (et != null) {
|
||||
et.setFocusable(true);
|
||||
et.setFocusableInTouchMode(true);
|
||||
et.requestFocus();
|
||||
imm.toggleSoftInputFromWindow(toGetWindowTokenView.getWindowToken()
|
||||
, InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//显示/隐藏输入法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
|
||||
//对输入字符判断<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
public final static int TYPE_NOT_ALLOWED_EMPTY = 0;
|
||||
public final static int TYPE_VERIFY = 1;
|
||||
public final static int TYPE_PASSWORD = 2;
|
||||
public final static int TYPE_PHONE = 3;
|
||||
public final static int TYPE_MAIL = 4;
|
||||
|
||||
private static ColorStateList oringinalHintColor;
|
||||
|
||||
/**判断edittext输入文字是否合法
|
||||
* @param context
|
||||
* @param et
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInputedCorrect(Activity context, EditText et) {
|
||||
return isInputedCorrect(context, et, TYPE_NOT_ALLOWED_EMPTY, null);
|
||||
}
|
||||
/**判断edittext输入文字是否合法
|
||||
* @param context
|
||||
* @param et
|
||||
* @param errorRemind
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInputedCorrect(Activity context, EditText et, String errorRemind) {
|
||||
return isInputedCorrect(context, et, TYPE_NOT_ALLOWED_EMPTY, errorRemind);
|
||||
}
|
||||
/**判断edittext输入文字是否合法
|
||||
* @param context
|
||||
* @param et
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInputedCorrect(Activity context, EditText et, int type) {
|
||||
return isInputedCorrect(context, et, type, null);
|
||||
}
|
||||
/**判断edittext输入文字是否合法
|
||||
* @param context
|
||||
* @param stringResId
|
||||
* @param et
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInputedCorrect(Activity context, int stringResId, EditText et) {
|
||||
return isInputedCorrect(context, et, TYPE_NOT_ALLOWED_EMPTY, stringResId);
|
||||
}
|
||||
/**判断edittext输入文字是否合法
|
||||
* @param context
|
||||
* @param et
|
||||
* @param type
|
||||
* @param stringResId
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInputedCorrect(Activity context, EditText et, int type, int stringResId) {
|
||||
try {
|
||||
if (context != null && stringResId > 0) {
|
||||
return isInputedCorrect(context, et, type, context.getResources().getString(stringResId));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "isInputedCorrect try { if (context != null && stringResId > 0) {catch (Exception e) \n" + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**判断edittext输入文字是否合法
|
||||
* @param context
|
||||
* @param et
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInputedCorrect(Activity context, EditText et, int type, String errorRemind) {
|
||||
if (context == null || et == null) {
|
||||
Log.e(TAG, "isInputedCorrect context == null || et == null >> return false;");
|
||||
return false;
|
||||
}
|
||||
oringinalHintColor = et.getHintTextColors();
|
||||
|
||||
String inputed = StringUtil.getTrimedString(et);
|
||||
switch (type) {
|
||||
case TYPE_VERIFY:
|
||||
if (type == TYPE_VERIFY && inputed.length() < 4) {
|
||||
return showInputedError(context, et, StringUtil.isNotEmpty(errorRemind, true) ? errorRemind : "验证码不能小于4位");
|
||||
}
|
||||
break;
|
||||
case TYPE_PASSWORD:
|
||||
if (inputed.length() < 6) {
|
||||
return showInputedError(context, et, StringUtil.isNotEmpty(errorRemind, true) ? errorRemind : "密码不能小于6位");
|
||||
}
|
||||
if (StringUtil.isNumberOrAlpha(inputed) == false) {
|
||||
return showInputedError(context, et, StringUtil.isNotEmpty(errorRemind, true) ? errorRemind : "密码只能含有字母或数字");
|
||||
}
|
||||
break;
|
||||
case TYPE_PHONE:
|
||||
if (inputed.length() != 11) {
|
||||
return showInputedError(context, et, StringUtil.isNotEmpty(errorRemind, true) ? errorRemind : "请输入11位手机号");
|
||||
}
|
||||
if (StringUtil.isPhone(inputed) == false) {
|
||||
Toast.makeText(context, "您输入的手机号格式不对哦~", Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case TYPE_MAIL:
|
||||
if (StringUtil.isEmail(inputed) == false) {
|
||||
return showInputedError(context, "您输入的邮箱格式不对哦~");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (StringUtil.isNotEmpty(inputed, true) == false || inputed.equals(StringUtil.getTrimedString(et.getHint()))) {
|
||||
return showInputedError(context, et, StringUtil.isNotEmpty(errorRemind, true) ? errorRemind : StringUtil.getTrimedString(et));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
et.setHintTextColor(oringinalHintColor);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**字符不合法提示(toast)
|
||||
* @param context
|
||||
* @param resId
|
||||
* @return
|
||||
*/
|
||||
public static boolean showInputedError(Activity context, int resId) {
|
||||
return showInputedError(context, null, resId);
|
||||
}
|
||||
/**字符不合法提示(et == null ? toast : hint)
|
||||
* @param context
|
||||
* @param et
|
||||
* @param resId
|
||||
* @return
|
||||
*/
|
||||
public static boolean showInputedError(Activity context, EditText et, int resId) {
|
||||
try {
|
||||
return showInputedError(context, et, context.getResources().getString(resId));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "" + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**字符不合法提示(toast)
|
||||
* @param context
|
||||
* @param string
|
||||
* @return
|
||||
*/
|
||||
public static boolean showInputedError(Activity context, String string) {
|
||||
return showInputedError(context, null, string);
|
||||
}
|
||||
/**字符不合法提示(et == null ? toast : hint)
|
||||
* @param context
|
||||
* @param et
|
||||
* @param string
|
||||
* @return
|
||||
*/
|
||||
public static boolean showInputedError(Activity context, EditText et, String string) {
|
||||
if (context == null || StringUtil.isNotEmpty(string, false) == false) {
|
||||
Log.e(TAG, "showInputedError context == null || et == null || StringUtil.isNotEmpty(string, false) == false >> return false;");
|
||||
return false;
|
||||
}
|
||||
if (et == null) {
|
||||
Toast.makeText(context, StringUtil.getTrimedString(string), Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
et.setText("");
|
||||
et.setHint(string);
|
||||
et.setHintTextColor(context.getResources().getColor(R.color.red));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//对输入字符判断>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.base.BaseAdapter;
|
||||
import zuo.biao.library.model.Entry;
|
||||
import zuo.biao.library.util.ImageLoaderUtil;
|
||||
import zuo.biao.library.util.Log;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**通用网格Adapter(url, name)
|
||||
* *适用于gridView
|
||||
* @author Lemon
|
||||
* @use new GridAdapter(...); 具体参考.DemoAdapter
|
||||
*/
|
||||
public class GridAdapter extends BaseAdapter<Entry<String, String>> {
|
||||
private static final String TAG = "GridAdapter";
|
||||
|
||||
public GridAdapter(Activity context) {
|
||||
this(context, R.layout.grid_item);
|
||||
}
|
||||
public GridAdapter(Activity context, int layoutRes) {
|
||||
super(context);
|
||||
setLayoutRes(layoutRes);
|
||||
}
|
||||
|
||||
private int layoutRes;//item视图资源
|
||||
public void setLayoutRes(int layoutRes) {
|
||||
this.layoutRes = layoutRes;
|
||||
}
|
||||
private boolean hasName = true;//是否显示名字
|
||||
public GridAdapter setHasName(boolean hasName) {
|
||||
this.hasName = hasName;
|
||||
return this;
|
||||
}
|
||||
private boolean hasCheck = false;//是否使用标记功能
|
||||
public GridAdapter setHasCheck(boolean hasCheck) {
|
||||
this.hasCheck = hasCheck;
|
||||
return this;
|
||||
}
|
||||
|
||||
//item标记功能,不需要可以删除<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
private HashMap<Integer, Boolean> hashMap;//实现选中标记的列表,不需要可以删除。这里可用List<Integer> checkedList代替
|
||||
public boolean getItemChecked(int position) {
|
||||
if (hasCheck == false) {
|
||||
Log.e(TAG, "<<< !!! hasCheck == false >>>>> ");
|
||||
return false;
|
||||
}
|
||||
return hashMap.get(position);
|
||||
}
|
||||
public void setItemChecked(int position, boolean isChecked) {
|
||||
if (hasCheck == false) {
|
||||
Log.e(TAG, "<<< !!! hasCheck == false >>>>> ");
|
||||
return;
|
||||
}
|
||||
hashMap.put(position, isChecked);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
//item标记功能,不需要可以删除>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
public int selectedCount = 0;
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
ViewHolder holder = convertView == null ? null : (ViewHolder) convertView.getTag();
|
||||
if (holder == null) {
|
||||
convertView = inflater.inflate(layoutRes, parent, false);
|
||||
|
||||
holder = new ViewHolder();
|
||||
holder.ivGridItemHead = (ImageView) convertView.findViewById(R.id.ivGridItemHead);
|
||||
if (hasName) {
|
||||
holder.tvGridItemName = (TextView) convertView.findViewById(R.id.tvGridItemName);
|
||||
}
|
||||
if (hasCheck) {
|
||||
holder.ivGridItemCheck = (ImageView) convertView.findViewById(R.id.ivGridItemCheck);
|
||||
}
|
||||
|
||||
convertView.setTag(holder);
|
||||
}
|
||||
|
||||
final Entry<String, String> kvb = getItem(position);
|
||||
final String name = kvb.getValue();
|
||||
|
||||
ImageLoaderUtil.loadImage(holder.ivGridItemHead, kvb.getKey());
|
||||
|
||||
if (hasName) {
|
||||
holder.tvGridItemName.setVisibility(View.VISIBLE);
|
||||
holder.tvGridItemName.setText(StringUtil.getTrimedString(name));
|
||||
}
|
||||
|
||||
if (hasCheck) {
|
||||
holder.ivGridItemCheck.setVisibility(View.VISIBLE);
|
||||
|
||||
holder.ivGridItemCheck.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setItemChecked(position, !getItemChecked(position));
|
||||
Log.i(TAG, (getItemChecked(position) ? "" : "取消") + "选择第 " + position + " 个item name=" + name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
public ImageView ivGridItemHead;
|
||||
public TextView tvGridItemName;
|
||||
public ImageView ivGridItemCheck;
|
||||
}
|
||||
|
||||
|
||||
/**刷新列表
|
||||
* @param list
|
||||
*/
|
||||
@Override
|
||||
public synchronized void refresh(List<Entry<String, String>> list) {
|
||||
if (list != null && list.size() > 0) {
|
||||
initList(list);
|
||||
}
|
||||
if (hasCheck) {
|
||||
selectedCount = 0;
|
||||
for (int i = 0; i < this.list.size(); i++) {
|
||||
if (getItemChecked(i) == true) {
|
||||
selectedCount ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**标记List<String>中的值是否已被选中。
|
||||
* 不需要可以删除,但“this.list = list;”这句
|
||||
* 要放到constructor【这个adapter只有ModleAdapter(Context context, List<Object> list)这一个constructor】里去
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint("UseSparseArrays")
|
||||
private void initList(List<Entry<String, String>> list) {
|
||||
this.list = list;
|
||||
if (hasCheck) {
|
||||
hashMap = new HashMap<Integer, Boolean>();
|
||||
if (list != null) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
hashMap.put(i, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.base.BaseAdapter;
|
||||
import zuo.biao.library.model.Entry;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**网格选择器adapter
|
||||
* @author Lemon
|
||||
* @use new GridPickerAdapter(...); 具体参考.DemoAdapter
|
||||
*/
|
||||
public class GridPickerAdapter extends BaseAdapter<Entry<Integer, String>> {
|
||||
// private static final String TAG = "GridPickerAdapter";
|
||||
|
||||
public static final int TYPE_CONTNET_ENABLE = 0;
|
||||
public static final int TYPE_CONTNET_UNABLE = 1;
|
||||
public static final int TYPE_TITLE = 2;
|
||||
|
||||
private OnItemSelectedListener onItemSelectedListener;
|
||||
public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
|
||||
this.onItemSelectedListener = onItemSelectedListener;
|
||||
}
|
||||
|
||||
private int currentPosition;//初始选中位置
|
||||
private int height;//item高度
|
||||
public GridPickerAdapter(Activity context, int currentPosition, int height) {
|
||||
super(context);
|
||||
this.currentPosition = currentPosition;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getCurrentPosition() {
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
public String getCurrentItemName() {
|
||||
return StringUtil.getTrimedString(getItem(getCurrentPosition()).getValue());
|
||||
}
|
||||
|
||||
|
||||
//getView的常规写法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
private LayoutParams layoutParams;
|
||||
@Override
|
||||
public View getView(final int position, View convertView, final ViewGroup parent) {
|
||||
ViewHolder holder = convertView == null ? null : (ViewHolder) convertView.getTag();
|
||||
if (holder == null) {
|
||||
convertView = inflater.inflate(R.layout.grid_picker_item, parent, false);
|
||||
holder = new ViewHolder();
|
||||
|
||||
holder.tv = (TextView) convertView.findViewById(R.id.tvGridPickerItem);
|
||||
|
||||
convertView.setTag(holder);
|
||||
}
|
||||
|
||||
final Entry<Integer, String> data = getItem(position);
|
||||
final int type = data.getKey();
|
||||
// if (isEnabled == false && position == currentPosition) {
|
||||
// currentPosition ++;
|
||||
// }
|
||||
|
||||
holder.tv.setText(StringUtil.getTrimedString(data.getValue()));
|
||||
holder.tv.setTextColor(resources.getColor(type == TYPE_CONTNET_ENABLE ? R.color.black : R.color.gray_2));
|
||||
holder.tv.setBackgroundResource(position == currentPosition
|
||||
? R.drawable.green_rounded_rectangle_normal : R.drawable.null_drawable);
|
||||
|
||||
convertView.setBackgroundResource(type == TYPE_TITLE ? R.color.alpha_1 : R.color.alpha_complete);
|
||||
|
||||
convertView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (type == TYPE_CONTNET_ENABLE) {
|
||||
currentPosition = position;
|
||||
if (onItemSelectedListener != null) {
|
||||
onItemSelectedListener.onItemSelected(null, v, position, getItemId(position));
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (height > 0) {
|
||||
if (layoutParams == null || layoutParams.height != height) {
|
||||
layoutParams = convertView.getLayoutParams();
|
||||
layoutParams.height = height;
|
||||
}
|
||||
convertView.setLayoutParams(layoutParams);
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
public TextView tv;
|
||||
}
|
||||
//getView的常规写法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
@ -1,363 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.base.BaseView;
|
||||
import zuo.biao.library.model.Entry;
|
||||
import zuo.biao.library.model.GridPickerConfig;
|
||||
import zuo.biao.library.util.Log;
|
||||
import zuo.biao.library.util.ScreenUtil;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.res.Resources;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.GridView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**网格选择器View
|
||||
* @author Lemon
|
||||
* @must 调用init方法
|
||||
* @use 参考 .DemoView
|
||||
*/
|
||||
public class GridPickerView extends BaseView<List<Entry<Integer, String>>> {
|
||||
private static final String TAG = "GridPickerView";
|
||||
|
||||
/**tabs切换和gridView的内容切换
|
||||
*/
|
||||
public interface OnTabClickListener {
|
||||
|
||||
void onTabClick(int tabPosition, TextView tvTab);
|
||||
}
|
||||
|
||||
private OnTabClickListener onTabClickListener;
|
||||
public void setOnTabClickListener(OnTabClickListener onTabClickListener) {
|
||||
this.onTabClickListener = onTabClickListener;
|
||||
}
|
||||
|
||||
|
||||
private OnItemSelectedListener onItemSelectedListener;
|
||||
public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
|
||||
this.onItemSelectedListener = onItemSelectedListener;
|
||||
}
|
||||
|
||||
private int contentHeight;
|
||||
public GridPickerView(Activity context, Resources resources) {
|
||||
super(context, resources);
|
||||
contentHeight = (int) getDimension(R.dimen.grid_picker_content_height);
|
||||
}
|
||||
|
||||
public LinearLayout llGridPickerViewTabContainer;
|
||||
public GridView gvGridPickerView;
|
||||
/**获取View
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
public View createView(LayoutInflater inflater) {
|
||||
convertView = inflater.inflate(R.layout.grid_picker_view, null);
|
||||
|
||||
llGridPickerViewTabContainer = findViewById(R.id.llGridPickerViewTabContainer);
|
||||
gvGridPickerView = findViewById(R.id.gvGridPickerView);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<GridPickerConfig> getConfigList() {
|
||||
return configList;
|
||||
}
|
||||
|
||||
public ArrayList<String> getSelectedItemList() {
|
||||
ArrayList<String> list = new ArrayList<String>();
|
||||
for (GridPickerConfig gpcb : configList) {
|
||||
list.add(gpcb.getSelectedItemName());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
public int getTabCount() {
|
||||
return configList == null ? 0 : configList.size();
|
||||
}
|
||||
|
||||
public boolean isOnFirstTab() {
|
||||
return getTabCount() <= 0 ? false : getCurrentTabPosition() <= 0;
|
||||
}
|
||||
public boolean isOnLastTab() {
|
||||
return getTabCount() <= 0 ? false : getCurrentTabPosition() >= getTabCount() - 1;
|
||||
}
|
||||
|
||||
private int currentTabPosition;
|
||||
public int getCurrentTabPosition() {
|
||||
return currentTabPosition;
|
||||
}
|
||||
|
||||
private String currentTabName;
|
||||
public String getCurrentTabName() {
|
||||
return currentTabName;
|
||||
}
|
||||
private String currentTabSuffix;
|
||||
public String getCurrentTabSuffix() {
|
||||
return currentTabSuffix;
|
||||
}
|
||||
|
||||
|
||||
public String currentSelectedItemName;
|
||||
public String getCurrentSelectedItemName() {
|
||||
return currentSelectedItemName;
|
||||
}
|
||||
public int currentSelectedItemPosition;
|
||||
public int getCurrentSelectedItemPosition() {
|
||||
return currentSelectedItemPosition;
|
||||
}
|
||||
|
||||
public String getSelectedItemName(int tabPosition) {
|
||||
return configList.get(tabPosition).getSelectedItemName();
|
||||
}
|
||||
public int getSelectedItemPosition(int tabPosition) {
|
||||
return configList.get(tabPosition).getSelectedItemPostion();
|
||||
}
|
||||
|
||||
|
||||
public List<Entry<Integer, String>> getList() {
|
||||
return adapter == null ? null : adapter.list;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void bindView(List<Entry<Integer, String>> l){/*do nothing,必须init**/}
|
||||
|
||||
|
||||
/**初始化,必须使用且只能使用一次
|
||||
* @param configList
|
||||
* @param lastList
|
||||
*/
|
||||
public final void init(ArrayList<GridPickerConfig> configList, List<Entry<Integer, String>> lastList) {
|
||||
if (configList == null || configList.size() <= 0) {
|
||||
Log.e(TAG, "initTabs (configList == null || configList.size() <= 0 " +
|
||||
">> selectedItemPostionList = new ArrayList<Integer>(); return;");
|
||||
return;
|
||||
}
|
||||
|
||||
currentTabPosition = configList.size() - 1;
|
||||
currentTabName = configList.get(currentTabPosition).getTabName();
|
||||
|
||||
int tabWidth = configList.size() < 4 ? ScreenUtil.getScreenWidth(context) / configList.size() : 3;
|
||||
llGridPickerViewTabContainer.removeAllViews();
|
||||
for (int i = 0; i < configList.size(); i++) {//需要重新设置来保持每个tvTab宽度一致
|
||||
|
||||
addTab(i, tabWidth, StringUtil.getTrimedString(configList.get(i)));
|
||||
}
|
||||
llGridPickerViewTabContainer.getChildAt(currentTabPosition)
|
||||
.setBackgroundResource(R.color.alpha_3);
|
||||
|
||||
this.configList = configList;
|
||||
|
||||
bindView(currentTabPosition, lastList, configList.get(currentTabPosition).getSelectedItemPostion());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**添加tab
|
||||
* @param tabPosition
|
||||
* @param tabWidth
|
||||
* @param name
|
||||
*/
|
||||
@SuppressLint("NewApi")
|
||||
private void addTab(final int tabPosition, int tabWidth, String name) {
|
||||
if (StringUtil.isNotEmpty(name, true) == false) {
|
||||
return;
|
||||
}
|
||||
name = StringUtil.getTrimedString(name);
|
||||
|
||||
final TextView tvTab = new TextView(context);
|
||||
tvTab.setLayoutParams(new LayoutParams(tabWidth, LayoutParams.MATCH_PARENT));
|
||||
tvTab.setGravity(Gravity.CENTER);
|
||||
// tvTab.setPaddingRelative(4, 12, 4, 12);
|
||||
tvTab.setTextColor(context.getResources().getColor(R.color.black));
|
||||
tvTab.setBackgroundResource(R.drawable.bg_pressed_common);
|
||||
tvTab.setTextSize(18);
|
||||
tvTab.setSingleLine(true);
|
||||
tvTab.setText(name);
|
||||
tvTab.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (tabPosition == getCurrentTabPosition()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (onTabClickListener != null) {
|
||||
onTabClickListener.onTabClick(tabPosition, tvTab);
|
||||
return;
|
||||
}
|
||||
//点击就是要切换list,这些配置都要改bindView(tabSuffix, tabPosition, tabName, list, numColumns, maxShowRows, itemPosition)
|
||||
}
|
||||
});
|
||||
llGridPickerViewTabContainer.addView(tvTab);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static final int MAX_NUM_TABS = 12;//最大标签数量
|
||||
|
||||
private ArrayList<GridPickerConfig> configList;
|
||||
private GridPickerAdapter adapter;
|
||||
/**设置并显示内容//可能导致每次都不变
|
||||
* @param tabPosition
|
||||
* @param list
|
||||
*/
|
||||
public void bindView(final int tabPosition, List<Entry<Integer, String>> list) {
|
||||
bindView(tabPosition, list, getSelectedItemPosition(tabPosition));
|
||||
}
|
||||
/**
|
||||
* @param tabPosition
|
||||
* @param list
|
||||
* @param itemPosition
|
||||
*/
|
||||
public void bindView(final int tabPosition, List<Entry<Integer, String>> list, int itemPosition) {//GridView
|
||||
if (configList == null || configList.size() <= 0) {
|
||||
Log.e(TAG, "bindView(final int tabPostion, final List<Entry<Integer, String>> list, final int itemPosition) {" +
|
||||
" >> configList == null || configList.size() <= 0 >> return;");
|
||||
return;
|
||||
}
|
||||
GridPickerConfig gpcb = configList.get(tabPosition);
|
||||
if (gpcb == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (list == null || list.size() <= 0) {
|
||||
Log.e(TAG, "bindView(final int tabPostion, final List<Entry<Integer, String>> list, final int itemPosition) {" +
|
||||
" >> list == null || list.size() <= 0 >> return;");
|
||||
return;
|
||||
}
|
||||
if (tabPosition >= MAX_NUM_TABS) {
|
||||
Log.e(TAG, "bindView tabPosition >= MAX_NUM_TABS,防止恶意添加标签导致数量过多选择困难甚至崩溃 >> return;");
|
||||
return;
|
||||
}
|
||||
|
||||
itemPosition = getItemPosition(itemPosition, list);
|
||||
|
||||
int numColumns = gpcb.getNumColumns();
|
||||
if (numColumns <= 0) {
|
||||
numColumns = 3;
|
||||
}
|
||||
|
||||
int maxShowRows = gpcb.getMaxShowRows();
|
||||
if (maxShowRows <= 0) {
|
||||
maxShowRows = 5;
|
||||
}
|
||||
|
||||
//Tabs<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
doOnItemSelected(tabPosition, itemPosition, list.get(itemPosition).getValue());
|
||||
|
||||
//Tabs>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
||||
//gridView<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
adapter = new GridPickerAdapter(context, itemPosition, contentHeight/maxShowRows);
|
||||
adapter.refresh(list);
|
||||
adapter.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
currentSelectedItemName = adapter.getCurrentItemName();
|
||||
if (isOnLastTab() == false && onItemSelectedListener != null) {
|
||||
onItemSelectedListener.onItemSelected(parent, view, position, id);
|
||||
return;
|
||||
}
|
||||
doOnItemSelected(tabPosition, position, adapter.getCurrentItemName());
|
||||
}
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {}
|
||||
});
|
||||
|
||||
gvGridPickerView.setNumColumns(numColumns);
|
||||
gvGridPickerView.setAdapter(adapter);
|
||||
gvGridPickerView.smoothScrollToPosition(itemPosition);
|
||||
|
||||
//gridView>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
}
|
||||
|
||||
private int length;
|
||||
/**获取itemPosition,解决部分不可点击的item被选中的问题
|
||||
* @param itemPosition
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
private int getItemPosition(int itemPosition, List<Entry<Integer, String>> list) {
|
||||
if (itemPosition < 0) {
|
||||
itemPosition = 0;
|
||||
} else if (itemPosition >= list.size()) {
|
||||
itemPosition = list.size() - 1;
|
||||
}
|
||||
|
||||
if (isItemEnabled(list, itemPosition) == false) {
|
||||
length = Math.max(itemPosition, list.size() - itemPosition);
|
||||
for (int i = 1; i <= length; i++) {
|
||||
if (isItemEnabled(list, itemPosition - i)) {
|
||||
Log.i(TAG, "getItemPosition return " + (itemPosition - i));
|
||||
return itemPosition - i;
|
||||
}
|
||||
if (isItemEnabled(list, itemPosition + i)) {
|
||||
Log.i(TAG, "getItemPosition return " + (itemPosition + i));
|
||||
return itemPosition + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.i(TAG, "getItemPosition return " + itemPosition);
|
||||
return itemPosition;
|
||||
}
|
||||
|
||||
private boolean isItemEnabled(List<Entry<Integer, String>> list, int itemPosition) {
|
||||
return list != null && itemPosition >= 0 && itemPosition < list.size()
|
||||
&& list.get(itemPosition).getKey() == GridPickerAdapter.TYPE_CONTNET_ENABLE;
|
||||
}
|
||||
|
||||
|
||||
/**在onItemSelected时响应,
|
||||
* 之后可能会跳转到下一个tab,导致 tabPositionWhenItemSelect+=1; selectedItemPosition = 0;
|
||||
* @param tabPosition
|
||||
* @param itemPosition
|
||||
* @param itemName
|
||||
*/
|
||||
public void doOnItemSelected(int tabPosition, int itemPosition, String itemName) {
|
||||
currentTabPosition = tabPosition < getTabCount() ? tabPosition : getTabCount() - 1;
|
||||
currentSelectedItemPosition = itemPosition;
|
||||
currentSelectedItemName = StringUtil.getTrimedString(itemName);
|
||||
|
||||
configList.set(currentTabPosition, configList.get(currentTabPosition).set(currentSelectedItemName, itemPosition));
|
||||
|
||||
for (int i = 0; i < llGridPickerViewTabContainer.getChildCount(); i++) {
|
||||
((TextView) llGridPickerViewTabContainer.getChildAt(i)).setText("" + configList.get(i).getTabName());
|
||||
llGridPickerViewTabContainer.getChildAt(i).setBackgroundResource(
|
||||
i == tabPosition ? R.color.alpha_3 : R.color.alpha_complete);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**通用纵向Item选项dialog
|
||||
* @author lemon
|
||||
* @use new ItemDialog(...).show();
|
||||
*/
|
||||
public class ItemDialog extends Dialog implements OnItemClickListener {
|
||||
// private static final String TAG = "ItemDialog";
|
||||
|
||||
public interface OnDialogItemClickListener {
|
||||
|
||||
/**点击item事件的回调方法
|
||||
* @param requestCode 传入的用于区分某种情况下的showDialog
|
||||
* @param position
|
||||
* @param item
|
||||
*/
|
||||
void onDialogItemClick(int requestCode, int position, String item);
|
||||
}
|
||||
|
||||
private Context context;
|
||||
private String[] items;
|
||||
private String title;
|
||||
|
||||
private int requestCode;
|
||||
private OnDialogItemClickListener listener;
|
||||
/**
|
||||
* 带监听器参数的构造函数
|
||||
*/
|
||||
public ItemDialog(Context context, String[] items,
|
||||
int requestCode, OnDialogItemClickListener listener) {
|
||||
this(context, items, null, requestCode, listener);
|
||||
}
|
||||
public ItemDialog(Context context, String[] items, String title,
|
||||
int requestCode, OnDialogItemClickListener listener) {
|
||||
super(context, R.style.MyDialog);
|
||||
|
||||
this.context = context;
|
||||
this.items = items;
|
||||
this.title = title;
|
||||
this.requestCode = requestCode;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
private TextView tvItemDialogTitle;
|
||||
private ListView lvItemDialog;
|
||||
private ArrayAdapter<String> adapter;
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.item_dialog);
|
||||
setCanceledOnTouchOutside(true);
|
||||
|
||||
tvItemDialogTitle = (TextView) findViewById(R.id.tvItemDialogTitle);
|
||||
lvItemDialog = (ListView) findViewById(R.id.lvItemDialog);
|
||||
|
||||
tvItemDialogTitle.setVisibility(StringUtil.isNotEmpty(title, true) ? View.VISIBLE : View.GONE);
|
||||
tvItemDialogTitle.setText("" + StringUtil.getCurrentString());
|
||||
|
||||
adapter = new ArrayAdapter<String>(context, R.layout.item_dialog_item, items);
|
||||
lvItemDialog.setAdapter(adapter);
|
||||
lvItemDialog.setOnItemClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (listener != null) {
|
||||
listener.onDialogItemClick(requestCode, position, adapter == null ? null : adapter.getItem(position));
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,69 +0,0 @@
|
||||
/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.*/
|
||||
|
||||
package zuo.biao.library.ui;
|
||||
|
||||
import zuo.biao.library.R;
|
||||
import zuo.biao.library.base.BaseAdapter;
|
||||
import zuo.biao.library.model.Entry;
|
||||
import zuo.biao.library.util.StringUtil;
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**key-value型(两个都是String类型)Adapter,
|
||||
* @author Lemon
|
||||
* @use new KeyValueAdapter(...); 具体参考.DemoAdapter
|
||||
*/
|
||||
public class KeyValueAdapter extends BaseAdapter<Entry<String, String>> {
|
||||
|
||||
private int layoutRes;//布局id
|
||||
public KeyValueAdapter(Activity context) {
|
||||
this(context, R.layout.key_value_item);
|
||||
}
|
||||
public KeyValueAdapter(Activity context, int layoutRes) {
|
||||
super(context);
|
||||
|
||||
this.layoutRes = layoutRes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
ViewHolder holder = convertView == null ? null : (ViewHolder) convertView.getTag();
|
||||
if (holder == null) {
|
||||
convertView = inflater.inflate(layoutRes, parent, false);
|
||||
|
||||
holder = new ViewHolder();
|
||||
holder.tvKey = (TextView) convertView.findViewById(R.id.tvKeyValueItemKey);
|
||||
holder.tvValue = (TextView) convertView.findViewById(R.id.tvKeyValueItemValue);
|
||||
|
||||
convertView.setTag(holder);
|
||||
}
|
||||
|
||||
final Entry<String, String> data = getItem(position);
|
||||
|
||||
holder.tvKey.setText(StringUtil.getTrimedString(data.getKey()));
|
||||
holder.tvValue.setText(StringUtil.getTrimedString(data.getValue()));
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
public TextView tvKey;
|
||||
public TextView tvValue;
|
||||
}
|
||||
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user