自定义控件第一批(列表选择,圆形图片,条形控件,短视频录制控件)
2017-04-28 12:52
393 查看
从上到下分别是:
列表选择控件、圆形图加载控件、条形布局控件、短视频录制控件。
代码下载:
自定义控件 短视频录制控件 列表选择 圆形图片 条形控件 - 下载频道 - CSDN.NET
http://download.csdn.net/detail/baidu_31093133/9828374
效果图:
使用方式:
/**
* 设置等页面条状控制或显示信息的控件
*/
public class LineControllerView extends LinearLayout {
}
列表选择控件、圆形图加载控件、条形布局控件、短视频录制控件。
代码下载:
自定义控件 短视频录制控件 列表选择 圆形图片 条形控件 - 下载频道 - CSDN.NET
http://download.csdn.net/detail/baidu_31093133/9828374
效果图:
列表选择:ListPickerDialog.java
传入需要展示的字符串数组即可。/** * 列表选项控件 */ public class ListPickerDialog extends DialogFragment { String[] list; String tag = "listPicker"; DialogInterface.OnClickListener listener; public void show(String[] list, FragmentManager fm, DialogInterface.OnClickListener listener){ this.list = list; this.listener = listener; show(fm, tag); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setItems(list, listener); return builder.create(); } }
使用方式:
private final String[] strs = new String[]{"三国", "江湖", "仙侠", "玄幻"}; new ListPickerDialog().show(strs, getSupportFragmentManager(), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { Toast.makeText(MainActivity.this, strs[i], Toast.LENGTH_SHORT).show(); } });
圆形图片:CircleImageView.java
支持加载:drawable、bitmap、resource、uri使用方式:
//drawable circleImageView.setImageDrawable(getResources().getDrawable(R.drawable.img1)); //bitmap Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img2); circleImageView.setImageBitmap(bitmap); //resource circleImageView.setImageResource(R.drawable.img3); //uri Uri uri = Uri.parse("android.resource://" + ctx.getPackageName() + "/" + R.raw.img4); circleImageView.setImageURI(uri);
/** * 圆形图片控件 */ public class CircleImageView extends ImageView { private Bitmap mBitmap; private BitmapShader mBitmapShader; private Paint paint; private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; private static final int COLORDRAWABLE_DIMENSION = 2; public CircleImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } @Override protected void onDraw(Canvas canvas) { if (mBitmap == null||mBitmapShader == null) { return; } if(mBitmap.getHeight() == 0 || mBitmap.getWidth() == 0) return; updateBitmapShader(); paint.setShader(mBitmapShader); canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, Math.min(getWidth() / 2.0f, getHeight() / 2.0f), paint); } private void init(){ if (mBitmap == null) return; mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); paint = new Paint(); paint.setAntiAlias(true); } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); mBitmap = bm; init(); } @Override public void setImageDrawable(Drawable drawable) { super.setImageDrawable(drawable); mBitmap = getBitmapFromDrawable(drawable); init(); } @Override public void setImageResource(@DrawableRes int resId) { super.setImageResource(resId); mBitmap = getBitmapFromDrawable(getDrawable()); init(); } @Override public void setImageURI(Uri uri) { super.setImageURI(uri); mBitmap = uri != null ? getBitmapFromDrawable(getDrawable()) : null; init(); } private Bitmap getBitmapFromDrawable(Drawable drawable) { if (drawable == null) { return null; } if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } try { Bitmap bitmap; if (drawable instanceof ColorDrawable) { bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); } Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } catch (Exception e) { e.printStackTrace(); return null; } } private void updateBitmapShader() { if (mBitmap == null) return; int canvasSize = Math.min(getWidth(), getHeight()); if (canvasSize == 0) return; if( canvasSize!= mBitmap.getWidth() || canvasSize != mBitmap.getHeight()) { Matrix matrix = new Matrix(); float scale = (float) canvasSize / (float) mBitmap.getWidth(); matrix.setScale(scale, scale); mBitmapShader.setLocalMatrix(matrix); } }
条形控件:LineControllerView .java
可以快速书写条形布局使用方式: 通过自定义标签来控制界面显示
例如:<com.example.hongda.myapplication.LineControllerView android:id="@+id/line3" android:layout_width="match_parent" android:layout_height="wrap_content" app:canNav="true" app:name="飞奔三千尺" /> <com.example.hongda.myapplication.LineControllerView android:id="@+id/line4" android:layout_width="match_parent" android:layout_height="wrap_content" app:isSwitch="true" app:name="异世邪君" />
<!-- 条形控制控件自定义属性 --> <declare-styleable name="LineControllerView"> <!-- 名称 --> <attr name="name" format="string" /> <!-- 内容或当前状态 --> <attr name="content" format="string" /> <!-- 是否是列表中最后一个 --> <attr name="isBottom" format="boolean" /> <!-- 是否可以跳转 --> <attr name="canNav" format="boolean" /> <!-- 是否是开关 --> <attr name="isSwitch" format="boolean" /> </declare-styleable>
/**
* 设置等页面条状控制或显示信息的控件
*/
public class LineControllerView extends LinearLayout {
private String name; private boolean isBottom; private String content; private boolean canNav; private boolean isSwitch; public LineControllerView(Context context, AttributeSet attrs) { super(context, attrs); LayoutInflater.from(context).inflate(R.layout.view_line_controller, this); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.LineControllerView, 0, 0); try { name = ta.getString(R.styleable.LineControllerView_name); content = ta.getString(R.styleable.LineControllerView_content); isBottom = ta.getBoolean(R.styleable.LineControllerView_isBottom, false); canNav = ta.getBoolean(R.styleable.LineControllerView_canNav,false); isSwitch = ta.getBoolean(R.styleable.LineControllerView_isSwitch,false); setUpView(); } finally { ta.recycle(); } } private void setUpView(){ TextView tvName = (TextView) findViewById(R.id.name); tvName.setText(name); TextView tvContent = (TextView) findViewById(R.id.content); tvContent.setText(content); View bottomLine = findViewById(R.id.bottomLine); bottomLine.setVisibility(isBottom ? VISIBLE : GONE); ImageView navArrow = (ImageView) findViewById(R.id.rightArrow); navArrow.setVisibility(canNav ? VISIBLE : GONE); LinearLayout contentPanel = (LinearLayout) findViewById(R.id.contentText); contentPanel.setVisibility(isSwitch ? GONE : VISIBLE); Switch switchPanel = (Switch) findViewById(R.id.btnSwitch); switchPanel.setVisibility(isSwitch?VISIBLE:GONE); } /** * 设置文字内容 * * @param content 内容 */ public void setContent(String content){ this.content = content; TextView tvContent = (TextView) findViewById(R.id.content); tvContent.setText(content); } /** * 获取内容 * */ public String getContent(){ TextView tvContent = (TextView) findViewById(R.id.content); return tvContent.getText().toString(); } /** * 设置是否可以跳转 * * @param canNav 是否可以跳转 * */ public void setCanNav(boolean canNav){ this.canNav = canNav; ImageView navArrow = (ImageView) findViewById(R.id.rightArrow); navArrow.setVisibility(canNav ? VISIBLE : GONE); } /** * 设置开关状态 * * @param on 开关 */ public void setSwitch(boolean on){ Switch mSwitch = (Switch) findViewById(R.id.btnSwitch); mSwitch.setChecked(on); } /** * 设置开关监听 * * @param listener 监听 */ public void setCheckListener(CompoundButton.OnCheckedChangeListener listener){ Switch mSwitch = (Switch) findViewById(R.id.btnSwitch); mSwitch.setOnCheckedChangeListener(listener); }
}
####布局文件:view_line_controller.xml
###短视频录制控件 ![短视频录制控件](http://img.blog.csdn.net/20170428122138401?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmFpZHVfMzEwOTMxMzM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 使用方式: 点击按钮之后调用VideoInputDialog.show方法即可 ```java case R.id.btn_short_video: if (ctx instanceof FragmentActivity) { FragmentActivity fragmentActivity = (FragmentActivity) ctx; if (requestVideo(fragmentActivity)) { VideoInputDialog.show(fragmentActivity.getSupportFragmentManager()); } } break; <div class="se-preview-section-delimiter"></div>
/** 摄像头预览界面控件 */ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private Camera mCamera; private static final String TAG = "CameraPreview"; public CameraPreview(Context context, Camera camera) { super(context); mCamera = camera; mHolder = getHolder(); mHolder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { try { if (mCamera == null) return; mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } catch (IOException e) { Log.d(TAG, "Error setting camera preview: " + e.getMessage()); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { // empty. Take care of releasing the Camera preview in your activity. } @Override public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { if (mCamera == null||mHolder.getSurface() == null){ // preview surface does not exist return; } // stop preview before making changes try { mCamera.stopPreview(); } catch (Exception e){ // ignore: tried to stop a non-existent preview } // set preview size and make any resize, rotate or // reformatting changes here // start preview with new settings try { mCamera.setPreviewDisplay(mHolder); mCamera.setDisplayOrientation(90); Camera.Parameters parameters=mCamera.getParameters(); parameters.set("orientation", "portrait"); parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); mCamera.setParameters(parameters); mCamera.startPreview(); } catch (Exception e){ Log.d(TAG, "Error starting camera preview: " + e.getMessage()); } } } /** * 小视频输入控件 */ public class VideoInputDialog extends DialogFragment { private static final String TAG = "VideoInputDialog"; private Camera mCamera; private CameraPreview mPreview; private ProgressBar mProgressRight, mProgressLeft; private MediaRecorder mMediaRecorder; private Timer mTimer; private final int MAX_TIME = 1500; private int mTimeCount; private long time; private boolean isRecording = false; private String fileName; private Handler mainHandler = new Handler(Looper.getMainLooper()); private Runnable updateProgress = new Runnable() { @Override public void run() { mProgressRight.setProgress(mTimeCount); mProgressLeft.setProgress(mTimeCount); } }; private Runnable sendVideo = new Runnable() { @Override public void run() { recordStop(); } }; public static VideoInputDialog newInstance() { VideoInputDialog dialog = new VideoInputDialog(); dialog.setStyle(DialogFragment.STYLE_NORMAL, R.style.maskDialog); return dialog; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.dialog_video_input, container, false); mCamera = getCameraInstance(); mPreview = new CameraPreview(getActivity(), mCamera); FrameLayout preview = (FrameLayout) v.findViewById(R.id.camera_preview); mProgressRight = (ProgressBar) v.findViewById(R.id.progress_right); mProgressLeft = (ProgressBar) v.findViewById(R.id.progress_left); mProgressRight.setMax(MAX_TIME); mProgressLeft.setMax(MAX_TIME); mProgressLeft.setRotation(180); ImageButton record = (ImageButton) v.findViewById(R.id.btn_record); record.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.i(TAG, "ACTION_DOWN " + isRecording); if (!isRecording) { if (prepareVideoRecorder()) { time = Calendar.getInstance().getTimeInMillis(); mMediaRecorder.start(); isRecording = true; mTimer = new Timer(); mTimer.schedule(new TimerTask() { @Override public void run() { mTimeCount++; mainHandler.post(updateProgress); if (mTimeCount == MAX_TIME) { mainHandler.post(sendVideo); } } }, 0, 10); } else { releaseMediaRecorder(); } } break; case MotionEvent.ACTION_UP: Log.i(TAG, "ACTION_UP"); recordStop(); break; } return true; } }); Log.i(TAG, "addView"); preview.addView(mPreview); return v; } @Override public void onPause() { super.onPause(); Log.i(TAG, "onPause"); recordStop(); releaseMediaRecorder(); releaseCamera(); } private void recordStop() { Log.i(TAG, "recordStop"); if (isRecording) { isRecording = false; if (isLongEnough()) { mMediaRecorder.stop(); } releaseMediaRecorder(); mCamera.lock(); if (mTimer != null) mTimer.cancel(); mTimeCount = 0; mainHandler.post(updateProgress); } } /** * 显示小视频输入控件 */ public static void show(FragmentManager ft) { DialogFragment newFragment = VideoInputDialog.newInstance(); newFragment.show(ft, "VideoInputDialog"); } /** * A safe way to get an instance of the Camera object. */ private static Camera getCameraInstance() { Camera c = null; try { c = Camera.open(); } catch (Exception e) { // Camera is not available (in use or does not exist) } return c; // returns null if camera is unavailable } private void releaseMediaRecorder() { Log.i(TAG, "releaseMediaRecorder"); if (mMediaRecorder != null) { mMediaRecorder.reset(); // clear recorder configuration mMediaRecorder.release(); // release the recorder object mMediaRecorder = null; mCamera.lock(); // lock camera for later use if (isLongEnough()) { Toast.makeText(getContext(), "发送短视频:" + getRecordFilePath(), Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getContext(), "录制时间过短", Toast.LENGTH_SHORT).show(); } dismiss(); } } private void releaseCamera() { if (mCamera != null) { mCamera.release(); // release the camera for other applications mCamera = null; } } private boolean prepareVideoRecorder() { Log.i(TAG, "prepareVideoRecorder"); if (mCamera == null) return false; mMediaRecorder = new MediaRecorder(); mCamera.unlock(); mMediaRecorder.setCamera(mCamera); mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P)); mMediaRecorder.setOutputFile(getOutputMediaFile().toString()); mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); try { mMediaRecorder.setOrientationHint(90); mMediaRecorder.prepare(); } catch (IllegalStateException e) { Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } catch (IOException e) { Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } return true; } /** * Create a File for saving an image or video */ private File getOutputMediaFile() { fileName = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".mp4"; File file = new File(getContext().getExternalCacheDir().getAbsolutePath() + "/" + fileName); Log.i(TAG, file.getAbsolutePath()); return file; } /** * 返回文件路径 * * @return */ private String getRecordFilePath() { if (TextUtils.isEmpty(fileName)) return ""; File file = new File(getContext().getExternalCacheDir().getAbsolutePath() + "/" + fileName); return file.getAbsolutePath(); } private boolean isLongEnough() { return Calendar.getInstance().getTimeInMillis() - time > 3000; } } <div class="se-preview-section-delimiter"></div>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <View android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <View android:layout_width="match_parent" android:layout_height="15dp" android:background="#25272A" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ProgressBar android:id="@+id/progress_left" style="@android:style/Widget.ProgressBar.Horizontal" android:layout_width="0dp" android:layout_height="2dp" android:layout_weight="1" android:progressDrawable="@drawable/style_recorder_progress" /> <ProgressBar android:id="@+id/progress_right" style="@android:style/Widget.ProgressBar.Horizontal" android:layout_width="0dp" android:layout_height="2dp" android:layout_weight="1" android:progressDrawable="@drawable/style_recorder_progress" /> </LinearLayout> <FrameLayout android:id="@+id/camera_preview" android:layout_width="match_parent" android:layout_height="280dp" android:orientation="vertical"> </FrameLayout> <View android:layout_width="match_parent" android:layout_height="2dp" android:background="#1173CB" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="102dp" android:background="#25272A"> <ImageButton android:id="@+id/btn_record" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@drawable/btn_video_record" /> </RelativeLayout> </LinearLayout>
相关文章推荐
- Android 图片单选/多选、拍照、裁剪、压缩。视频选择和录制
- 【Vue】vue 嵌入app内部,调用app的选择图片和录制视频功能的时候,当前的.vue文件方法失效
- galleryfinal 实现Android图片单选/多选、拍照、裁剪、压缩。视频选择和录制。
- EXT 可选择图片列表的表单控件实现
- Android自定义组合控件--图片加文字,类似视频播放软件的列表
- 一行代码完成 调用系统相册 和 视频,语音库,选择图片,视频,和音频文件。在选择界面实现了录制视频和录制音频功能。 截图
- android多图选择 图片/视频 单选or多选,以及视频录制
- KrGallery,拍照和选择图片,裁剪,录制视频和选择视频靠它了
- File文件控件,选中文件(图片,flash,视频)即立即预览显示
- File文件控件,选中文件(图片,flash,视频)即立即预览显示
- File文件控件,选中文件(图片,flash,视频)即立即预览显示
- 改变 propertygrid 控件的编辑风格(4)——加入选择列表
- 打造完美SWT日期选择控件:(三)看上去像下拉列表
- Eric的日期选择下拉列表小控件
- Java的常用方法--选择控件和滚动列表
- asp.net2.0推荐一个功能强大的图片选择控件
- Eric的日期选择下拉列表小控件
- 日期选择下拉列表小控件
- 打造完美SWT日期选择控件:(四)下拉列表的整体设计
- Eric的日期选择下拉列表小控件