自定义的messagebar

之前不是说我花大心血写了一个可以左右侧滑的自定义messagebar么

现在项目不要他了,要删掉了那就记录一下把,说不定以后或者大家参考下。

大致原理如下图:



package com.norca.casing.ui.view;

import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import com.norca.casing.R;

/**
 * Created by llsxily on 2015/9/6.
 * 整个bar的长度为2个屏幕宽度,发送信息的BAR是在一个screenWidth的位置,而录音的bar在0的位置
 * 所以在控制滚动的时候如果需要把左边的录音条滚出来的话应该是滚到0
 */
public class RecordBar extends ViewGroup implements View.OnClickListener{


    private Context context;

    private View mMessageBar;
    private View mRecordBar;

    private TextView mSlideText;
    private TextView mTimeText;

    //临时
    public EditText mMessageEditText;


    private int screenWidth;
    private ImageView mCallrecordBtn;
    private ImageView mFileBtn;
    private Button mMuteBtn;
    private Button mRecordBtn;
    private ImageView mEmotionBtn;

    private onRecordBarClickListener listener;

    public RecordBar(Context context) {
        super(context);
        init(context);
    }

    public RecordBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public RecordBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    //改变空间的宽度
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //measure的作用就是要测量控件高度并且修改measureHeight所以要用到新的高度的地方要放在测量之后
        mMessageBar.measure(screenWidth, mMessageBar.getMeasuredHeight());
        mRecordBar.measure(screenWidth, mRecordBar.getMeasuredHeight());
        //设置本ViewGroup的宽高
        setMeasuredDimension(2 * screenWidth, mMessageBar.getMeasuredHeight());
    }


    //init之后调用onmeasure
    //onmeasure完成后会调用layout
    //如果有设置背景的话还会调用Ondraw方法
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        mMessageBar.layout(screenWidth, l, 2 * screenWidth, l + mMessageBar.getMeasuredHeight());
        mRecordBar.layout(0, getMeasuredHeight() - mRecordBar.getMeasuredHeight() , screenWidth, getMeasuredHeight());
    }

    //设置默认滚动1个屏幕的距啦,把message亮出来
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        this.scrollTo((screenWidth), 0);
    }


    private void init(final Context context){
        this.context = context;
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        screenWidth = wm.getDefaultDisplay().getWidth();
        LayoutParams lp = new LayoutParams(screenWidth,LayoutParams.WRAP_CONTENT);
        mMessageBar = View.inflate(context, R.layout.messagebar, null);
        mMessageBar.setLayoutParams(lp);
        addView(mMessageBar);
        mRecordBar = View.inflate(context, R.layout.recordbar,null);
        mRecordBar.setLayoutParams(lp);
        addView(mRecordBar);
        requestLayout();
        mSlideText = (TextView)mRecordBar.findViewById(R.id.tv_recordbar_slideback);
        mCallrecordBtn = (ImageView)mMessageBar.findViewById(R.id.btn_recordbar_callrecord);
        mFileBtn = (ImageView)mMessageBar.findViewById(R.id.btn_recordbar_more);
        mMessageEditText = (EditText)mMessageBar.findViewById(R.id.edit_recordbar_messageedit);
        mEmotionBtn = (ImageView)mMessageBar.findViewById(R.id.btn_recordbar_emition);
        mMessageEditText.addTextChangedListener(mTextWatcher);
        mMuteBtn = (Button)mRecordBar.findViewById(R.id.btn_recordbar_mute);
        mRecordBtn = (Button)mRecordBar.findViewById(R.id.btn_recordbar_callrecord);
        mTimeText = (TextView)mRecordBar.findViewById(R.id.tv_recordbar_time);

        //改两个text宽度
        mMessageEditText.getLayoutParams().width = screenWidth  - mFileBtn.getLayoutParams().width - mCallrecordBtn.getLayoutParams().width;
        mSlideText.getLayoutParams().width = screenWidth - mMuteBtn.getLayoutParams().width - mRecordBtn.getLayoutParams().width - mTimeText.getLayoutParams().width;
        mSlideText.getLayoutParams().height = LayoutParams.MATCH_PARENT;
        requestLayout();
        mCallrecordBtn.setOnClickListener(this);
        mFileBtn.setOnClickListener(this);
        mRecordBar.setOnTouchListener(mTouchListener);
        mEmotionBtn.setOnClickListener(this);
        mMessageEditText.setOnClickListener(this);
    }



    TextWatcher mTextWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            if(s.length() == 0){
                //添加添加文字后变化代码
            }
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    };

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_recordbar_callrecord:
                openRecordBar();
                break;
            case R.id.btn_recordbar_more:
                listener.onMoreClick();
                break;
            case R.id.edit_recordbar_messageedit:
                listener.onEditTextClick();
                break;
            case R.id.btn_recordbar_emition:
                listener.onEmotionClick();
                break;
        }
    }


    OnTouchListener mTouchListener  = new OnTouchListener() {
        float lastX;
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    lastX  = event.getX();
                    break;
                case MotionEvent.ACTION_MOVE:
                    float x = lastX - event.getX();
                    if(RecordBar.this.getScrollX() <= screenWidth && RecordBar.this.getScrollX() >= 0){
                        if(RecordBar.this.getScrollX() > 50){
                            mSlideText.setText("T T 再拉就说再见了,放手我还爱你");
                        }
                        if(RecordBar.this.getScrollX() > 200){
                            mSlideText.setText("88~");
                        }
                        if(x > 0){
                            RecordBar.this.scrollBy((int)(1.3 * x),0);
                            lastX = event.getX();
                        }
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    if(RecordBar.this.getScrollX() > 200){
                        closeRecordBar();
                    }else {
                        openRecordBar();
                    }
                    break;
            }
            return true;
        }
    };

    public  void closeRecordBar(){
        final int distant = screenWidth - this.getScrollX();
        final int begin = this.getScrollX();
        Animation closeBarAnimation = new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
                if(interpolatedTime != 1){
                    RecordBar.this.scrollTo(begin + (int) (interpolatedTime * distant), 0);
                }else {
                    RecordBar.this.scrollTo(screenWidth, 0);
                    mSlideText.setText("左滑返回");
                }
            }

            @Override
            public boolean willChangeBounds() {
                return true;
            }
        };
        closeBarAnimation.setDuration(Math.abs(500 * distant / screenWidth));
        this.startAnimation(closeBarAnimation);

    }

    public void openRecordBar(){
        final int nowLocation = this.getScrollX();
        Animation openBarAnimation = new Animation() {
            @Override
            protected void applyTransformation(float interpolatedTime, Transformation t) {
                if(interpolatedTime != 1){
                    RecordBar.this.scrollTo((int) ((1 - interpolatedTime) * nowLocation), 0);
                }else {
                    RecordBar.this.scrollTo(0, 0);
                    mSlideText.setText("左滑返回");
                }
            }

            @Override
            public boolean willChangeBounds() {
                return true;
            }
        };
        openBarAnimation.setDuration(Math.abs(500 * nowLocation / screenWidth));
        this.startAnimation(openBarAnimation);
    }

    public interface onRecordBarClickListener{
        void onMoreClick();
        void onEditTextClick();
        void onEmotionClick();
    }

    public void setOnRecordBarClickListener(onRecordBarClickListener listener){
        this.listener = listener;
    }

}

recordbar.xml(这边还没做到就夭折了,不知道是幸运还是不幸,效果图比较难看一些)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_recordbar_record"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
<Button
    android:id="@+id/btn_recordbar_mute"
    android:layout_width="60dp"
    android:layout_height="wrap_content"
    android:text="静音"
    android:layout_alignParentBottom="true"

    />
<TextView
    android:id="@+id/tv_recordbar_time"
    android:layout_width="40dp"
    android:layout_height="match_parent"
    android:text="time"
    android:layout_toRightOf="@+id/btn_recordbar_mute"
    android:layout_centerVertical="true"
    android:gravity="center"
    android:background="@color/red"
    />
<TextView
    android:id="@+id/tv_recordbar_slideback"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:text="左滑"
    android:textColor="@color/black"
    android:layout_centerVertical="true"
    android:layout_toRightOf="@+id/tv_recordbar_time"
    android:gravity="center"
    android:background="@color/blue"
    />
<Button
    android:id="@+id/btn_recordbar_callrecord"
    android:layout_width="60dp"
    android:layout_height="wrap_content"
    android:text="录音"
    android:layout_alignParentBottom="true"
    android:layout_toRightOf="@+id/tv_recordbar_slideback"
    android:layout_alignParentRight="true"
    />
</RelativeLayout>


messagebar.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:id="@+id/ll_recordbar_message"
    android:layout_width="match_parent"
    android:layout_height="61dp"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/bg_recordbar"
    >
<ImageView
    android:id="@+id/btn_recordbar_callrecord"
    android:layout_width="50dp"
    android:layout_height="wrap_content"
    android:src="@drawable/recordbar_record"
    android:layout_centerVertical="true"
    />
    <RelativeLayout
        android:id="@+id/rl_recordbar_messagebox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/btn_recordbar_callrecord"
        android:layout_centerVertical="true"
        >

<com.rockerhieu.emojicon.EmojiconEditText
    android:id="@+id/edit_recordbar_messageedit"
    android:layout_width="290dp"
    android:layout_height="wrap_content"
    android:singleLine="false"
    android:maxLines="3"
    android:textSize="18sp"
    android:paddingRight="29dp"
    />
    <ImageView
        android:id="@+id/btn_recordbar_emition"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/recordbar_emotion"
        android:layout_alignRight="@+id/edit_recordbar_messageedit"
        android:layout_alignBottom="@+id/edit_recordbar_messageedit"
        android:layout_alignTop="@+id/edit_recordbar_messageedit"
        android:layout_marginRight="7dp"
        android:clickable="true"
        />

    </RelativeLayout>
<ImageView
    android:id="@+id/btn_recordbar_more"
    android:layout_width="50dp"
    android:layout_height="match_parent"
    android:src="@drawable/record_more"
    android:layout_toRightOf="@id/rl_recordbar_messagebox"
    android:layout_centerVertical="true"
    android:layout_alignParentRight="true"
    />
</RelativeLayout>


CCF大数据与计算智能大赛-面向电信行业存量用户的智能套餐个性化匹配模型联通赛-复赛第二名-【多分类,embedding】.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值