之前不是说我花大心血写了一个可以左右侧滑的自定义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>