模拟视频播放器控制界面时动画效果出现的问题
来源:互联网 发布:c语言做图形界面 编辑:程序博客网 时间:2024/06/10 14:01
需求:
项目要实现一个类似视频播放器控制界面的效果,不过比他简单些,显示有三个部分组成:最上面进行时间和下面的两个控制按钮,点击后屏幕显示,过几秒自动消失。
首先想到的就是前几天刚看的MediaController,所以就把MediaController拿过来简单的看了下,想貌似没有它复杂,赶进度要紧,自己简单实现就好,最后效果如下:
实现思路:
自定义一个view,上面是一个显示时间的文本,设下透明度;下面用一个FrameLayout,先放纵向放两个线性布局在最底层实现下面白条效果,然后把两个文本按钮加在上层;最后在稍微加点进入和退出的动画效果(这个地方出了点粗心的问题,下面提到)。
实现:
首先是自定义view:
public class VideoControlPanel extends FrameLayout implements IVideoControlPanel, AnimationListener, OnTouchListener,Runnable {private static final int DELAYMILLIS = 3 * 1000;private static final int DURATION = 300;private boolean isShowing = false;private Animation topEnter, topExit, buttomEnter, buttomExit;private View mRoot;private TextView tvTitle;private LinearLayout llTitle, llChange, llHangup;private FrameLayout flOperate;private Handler handler = new Handler();public VideoControlPanel(Context context) {super(context);initControllerPanel();}public VideoControlPanel(Context context, AttributeSet attrs) {super(context, attrs);initControllerPanel();}private void initControllerPanel() {initOther();initView();}private void initView() {LayoutInflater inflate = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);mRoot = inflate.inflate(R.layout.media_controller, null);llTitle = (LinearLayout) mRoot.findViewById(R.id.llTitle);flOperate = (FrameLayout) mRoot.findViewById(R.id.flOperate);tvTitle = (TextView) mRoot.findViewById(R.id.tvTitle);llHangup = (LinearLayout) mRoot.findViewById(R.id.llHangup);llChange = (LinearLayout) mRoot.findViewById(R.id.llChange);setOnTouchListener(this);addView(mRoot);show();}private void initOther() {topEnter = new TranslateAnimation(0, 0, -100, 0);topEnter.setDuration(DURATION);topExit = new TranslateAnimation(0, 0, 0, -100);topExit.setDuration(DURATION);topExit.setAnimationListener(this);buttomEnter = new TranslateAnimation(0, 0, 300, 0);buttomEnter.setDuration(DURATION);buttomExit = new TranslateAnimation(0, 0, 0, 100);buttomExit.setDuration(DURATION);}@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {if (mRoot != null) {mRoot.setVisibility(View.GONE);}}@Overridepublic void onAnimationRepeat(Animation animation) {}@Overridepublic void hide() {isShowing = false;llTitle.startAnimation(topExit);flOperate.startAnimation(buttomExit);}@Overridepublic void show() {if (!isShowing) {mRoot.setVisibility(View.VISIBLE);isShowing = true;llTitle.startAnimation(topEnter);flOperate.setAnimation(buttomEnter);}handler.removeCallbacks(this);handler.postDelayed(this, DELAYMILLIS);}@Overridepublic void run() {hide();}@Overridepublic void setTitle(String title) {if (tvTitle != null) {tvTitle.setText(title);}}@Overridepublic View getHangupView() {return llHangup;}@Overridepublic View getChangeView() {return llChange;}@Overridepublic void setOnClickListener(OnClickListener listener) {// super.setOnClickListener(l);if (llHangup != null) {llHangup.setOnClickListener(listener);}if (llChange != null) {llChange.setOnClickListener(listener);}}@Overridepublic boolean onTouch(View v, MotionEvent event) {show();return false;}}interface IVideoControlPanel {/** * 隐藏操作面板 */public void hide();/** * 显示操作面板 */public void show();/** * 设置标题 * * @param title */public void setTitle(String title);/** * 获取挂断的View * * @return */public View getHangupView();/** * 获取切换的View * * @return */public View getChangeView();}代码比较简单,所以也就没写注释。先加载xml中定义的布局,然后处理touch事件,最后用一个handle处理界面的消失。下面是布局文件:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/llTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:background="#88FFFFFF" android:gravity="center" android:orientation="horizontal" android:padding="8dip" > <TextView android:id="@+id/tvTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="通话时间:15分27秒" android:textSize="14sp" /> </LinearLayout> <FrameLayout android:id="@+id/flOperate" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:orientation="horizontal" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <ImageView android:layout_width="match_parent" android:layout_height="40dp" android:src="#00FFFFFF" /> <ImageView android:layout_width="match_parent" android:layout_height="40dp" android:src="#88FFFFFF" /> </LinearLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="12dp" > <LinearLayout android:id="@+id/llHangup" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_marginLeft="42dp" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:drawablePadding="4dp" android:drawableTop="@drawable/ic_hangup" android:gravity="center" android:text="挂断" /> </LinearLayout> <LinearLayout android:id="@+id/llChange" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="42dp" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:drawablePadding="4dp" android:drawableTop="@drawable/ic_change" android:gravity="center" android:text="切换" /> </LinearLayout> </RelativeLayout> </FrameLayout></RelativeLayout>这个布局的实现思路如上所述。然后就可以使用了,在需要的地方做如下引用:
<com.ttdevs.customcontrolpanel.VideoControlPanel android:id="@+id/vcpPanel" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:background="@drawable/bg" />这样就完成了所需效果。
遇到的问题:
在弄动画的时候,出了点问题,折腾了好久,现象为:底部的按钮出现的动画只有程序第一次启动的时候有效,之后就再没效果了。由于对动画不熟悉,也不知道怪什么,开始是像上面那么写的,最后实在没办法做如下修改,即每次都创建buttomEnter,竟然解决问题了:
@Overridepublic void show() {if (!isShowing) {mRoot.setVisibility(View.VISIBLE);isShowing = true;llTitle.startAnimation(topEnter);buttomEnter = new TranslateAnimation(0, 0, 300, 0);buttomEnter.setDuration(DURATION);flOperate.setAnimation(buttomEnter);}handler.removeCallbacks(this);handler.postDelayed(this, DELAYMILLIS);}
虽然效果实现了,但是一直纠结这个动画问题出在哪里。今天整理的时候无意中发现竟然是自己调用有问题导致的:
flOperate.setAnimation(buttomEnter);应该改成:flOperate.startAnimation(buttomEnter);
这样问题就解决了。
最新修改:2013-12-09
上面的问题虽然坚决了,却不知道问题出在哪,为什么解决,今天无意中看到一篇文章(来自:wangjinyu501),又拿过来研究了下,
public void setAnimation (Animation animation)
Sets the next animation to play for this view. If you want the animation to play immediately, use startAnimation(android.view.animation.Animation)
instead. This method provides allows fine-grained control over the start time and invalidation, but you must make sure that 1) the animation has a start time set, and 2) the view's parent (which controls animations on its children) will be invalidated when the animation is supposed to start.
Parameters
buttomEnter.setStartTime(Animation.START_ON_FIRST_FRAME);这样即可。那为什么每次都创建就可以播放动画呢,有兴趣可以看看setStartTime的源码或者打印下buttomEnter.hasStarted()的值。
去掉了布局文件后代码:
public class VideoControlPanel extends FrameLayout implements IVideoControlPanel, AnimationListener, OnTouchListener,Runnable {private static final int DELAYMILLIS = 3 * 1000; // 显示延时private static final int DURATION = 300; // 动画持续private boolean isShowing = false;private Animation topEnter, topExit, buttomEnter, buttomExit;private View mRoot;private TextView tvTitle;private RelativeLayout rlParent, rlOperate;private LinearLayout llTitle, llChange, llHangup, llOperateBg;private FrameLayout flOperate;private Handler handler = new Handler();public VideoControlPanel(Context context) {super(context);initControllerPanel();}public VideoControlPanel(Context context, AttributeSet attrs) {super(context, attrs);initControllerPanel();}private void initControllerPanel() {initOther();initView();}private void initView() {mRoot = initCustomView();setOnTouchListener(this);addView(mRoot);show();}private View initCustomView() {rlParent = new RelativeLayout(getContext());rlParent.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));// 上部分llTitle = new LinearLayout(getContext());llTitle.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 60));llTitle.setOrientation(LinearLayout.VERTICAL);llTitle.setBackgroundColor(Color.parseColor("#90FFFFFF")); // TODOllTitle.setGravity(Gravity.CENTER);tvTitle = new TextView(getContext());tvTitle.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));tvTitle.setGravity(Gravity.CENTER);tvTitle.setTextSize(18);llTitle.addView(tvTitle);RelativeLayout.LayoutParams rlpTop = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.WRAP_CONTENT);rlpTop.addRule(RelativeLayout.ALIGN_PARENT_TOP);rlParent.addView(llTitle, rlpTop);// 下部分flOperate = new FrameLayout(getContext());flOperate.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.WRAP_CONTENT));// 下部分背景llOperateBg = new LinearLayout(getContext());llOperateBg.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));llOperateBg.setOrientation(LinearLayout.VERTICAL);addBackgroundView("#00FFFFFF");addBackgroundView("#90FFFFFF");flOperate.addView(llOperateBg);// 下部分按钮rlOperate = new RelativeLayout(getContext());rlOperate.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT));// 下部分按钮挂断llHangup = getButtomLayout("挂断", R.drawable.ic_hangup);addBottomView(true, llHangup);// 下部分按钮切换llChange = getButtomLayout("切换", R.drawable.ic_change);addBottomView(false, llChange);flOperate.addView(rlOperate);RelativeLayout.LayoutParams rlpBottom = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);rlpBottom.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);rlParent.addView(flOperate, rlpBottom);return rlParent;}private void addBackgroundView(String color) {ImageView ivBg = new ImageView(getContext());ivBg.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 80));ivBg.setBackgroundColor(Color.parseColor(color));llOperateBg.addView(ivBg);}private LinearLayout getButtomLayout(String text, int drawId) {LinearLayout llChange = new LinearLayout(getContext());llChange.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));llChange.setOrientation(LinearLayout.VERTICAL);TextView tvChange = new TextView(getContext());tvChange.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));tvChange.setText(text);tvChange.setTextSize(18);tvChange.setTextColor(Color.parseColor("#FF393939"));tvChange.setGravity(Gravity.CENTER);tvChange.setCompoundDrawablePadding(2);tvChange.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(drawId), null, null);llChange.addView(tvChange);return llChange;}private void addBottomView(boolean isLeft, LinearLayout view) {RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);lp.addRule(RelativeLayout.CENTER_VERTICAL);if (isLeft) {lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);lp.leftMargin = 88;} else {lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);lp.rightMargin = 88;}rlOperate.addView(view, lp);}private void initOther() {topEnter = new TranslateAnimation(0, 0, -100, 0);topEnter.setDuration(DURATION);topExit = new TranslateAnimation(0, 0, 0, -100);topExit.setDuration(DURATION);topExit.setAnimationListener(this);buttomEnter = new TranslateAnimation(0, 0, 300, 0);buttomEnter.setDuration(DURATION);buttomExit = new TranslateAnimation(0, 0, 0, 100);buttomExit.setDuration(DURATION);}@Overridepublic void onAnimationStart(Animation animation) {// do nothing}@Overridepublic void onAnimationEnd(Animation animation) {if (mRoot != null) {mRoot.setVisibility(View.GONE);}}@Overridepublic void onAnimationRepeat(Animation animation) {// do nothing}@Overridepublic void hide() {isShowing = false;llTitle.startAnimation(topExit);flOperate.startAnimation(buttomExit);}@Overridepublic void show() {if (!isShowing) {mRoot.setVisibility(View.VISIBLE);isShowing = true;llTitle.startAnimation(topEnter);flOperate.startAnimation(buttomEnter);}handler.removeCallbacks(this);handler.postDelayed(this, DELAYMILLIS);}@Overridepublic void run() {hide();}@Overridepublic void setTitle(String title) {if (tvTitle != null) {tvTitle.setText(title);}}@Overridepublic View getHangupView() {return llHangup;}@Overridepublic View getChangeView() {return llChange;}@Overridepublic boolean onTouch(View v, MotionEvent event) {show();return false;}}interface IVideoControlPanel {/** * 隐藏操作面板 */public void hide();/** * 显示操作面板 */public void show();/** * 设置标题 * * @param title */public void setTitle(String title);/** * 获取挂断的View * * @return */public View getHangupView();/** * 获取切换的View * * @return */public View getChangeView();}
- 模拟视频播放器控制界面时动画效果出现的问题
- 控制界面切换的动画效果
- qt之界面的出现与消失的动画效果
- VideoView播放视频的时候出现播放前透明问题
- 界面出现奇怪的动画,各种移动效果
- Qt之界面出现、消失动画效果
- Qt之界面出现、消失动画效果
- Qt之界面出现、消失动画效果
- Qt之界面出现、消失动画效果
- Qt之界面出现、消失动画效果
- 播放视频的引导界面
- 关于代码控制unity中动画播放的问题
- OpenCV Trackbar 控制视频播放 cvSetTrackbarPos 的问题
- VideoView播放视频是出现黑边的问题
- VideoView播放视频是出现黑边的问题
- 模拟视频播放器练习
- 欢迎界面的动画效果
- 视频播放的问题
- POJ - 3061 Subsequence
- Java线程详解
- 【20131201】HDU1001
- zookeeper使用命令zkServer.sh status时出现错误提示问题
- 关于IOCP完成端口的文章
- 模拟视频播放器控制界面时动画效果出现的问题
- LDA-math-认识Beta/Dirichlet分布(1)
- poj1080
- UVA12538 Version Controlled IDE (可持久化Treap)
- jquery 自定义动画
- OC之【NSString字符串的其他用法】
- jobclient 源码分析
- 十四周学习计划
- 【SQL Server高可用性】数据库复制:SQL Server 2008R2中通过数据库复制,把A表的数据复制到B表