自定义控件第一批(列表选择,圆形图片,条形控件,短视频录制控件)

从上到下分别是:
列表选择控件、圆形图加载控件、条形布局控件、短视频录制控件。

代码下载:
自定义控件 短视频录制控件 列表选择 圆形图片 条形控件 - 下载频道 - 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


###短视频录制控件


![短视频录制控件](https://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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值