本学期学习了移动软件开发课程后,自己尝试实现了两个小功能,一个是利用OntouchListener()实现轨迹球滑动功能;一个是用Service实现一个简单播放器功能。 1.使用OnTouchListener()监听器实现一个轨迹球随着食指滑动运动; 当按下手指的时候记录手指的坐标作为起始坐标,当手指抬起的时候把当前手指坐标与起始坐标对比,由此可以判断手指滑动的方向。 Android提供的基于事件监听接口有OnClickListener、OnLongClickListener、OnFocusChangeListener、OnKeyListener、OnTouchListener、OnCreateContextMenuListener等。 OnClickListener接口:该接口处理的是点击事件。在触摸模式下,是在某个View上按下并抬起的组合动作,而在键盘模式下,是某个View获得焦点后点击确定键或者按下轨迹球事件。 OnLongClickListener接口: OnLongClickListener接口与上述的OnClickListener接口原理基本相同,只是该接口为View长按事件的捕捉接口,即当长时间按下某个View时触发的事件。 OnFocusChangeListener接口:OnFocusChangeListener接口用来处理控件焦点发生改变的事件。如果注册了该接口,当某个控件失去焦点或者获得焦点时都会触发该接口中的回调方法。 OnKeyListener接口:是对手机键盘进行监听的接口,通过对某个View注册并监听,当View获得焦点并有键盘事件时,便会触发该接口中的回调方法。 OnTouchListener接口:是用来处理手机屏幕事件的监听接口,当为View的范围内触摸按下、抬起或滑动等动作时都会触发该事件。 OnCreateContextMenuListener接口:是用来处理上下文菜单显示事件的监听接口。该方法是定义和注册上下文菜单的另一种方式。 主要代码: 布局文件: 在设置监听器利用匿名监听类public boolean onTouchEvent(MotionEvent event) 方法,进行监听的设置,其中监听Touch时,有一些动作需要注意,ACTION_DOWN,ACTION_MOVE,ACTION_UP分别指的是屏幕开始触摸,滑动,离开屏幕动作,设置完以后,尤其要注意返回值的作用,具体情况如下: 1.如果返回值为true,那么系统会连续处理触摸事件,处理完一个触摸事件以后,不会执行结束,而是准备执行下一次操作。 2.如果返回值为flase,那么系统只会处理触摸事件一次,处理完后,就以结束为准,不会再触发事件的处理。 1.播放器具有开始/暂停,跳转到下/上一首歌功能。实现通过一个Activity远程绑定和打开该Service。 Service是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。服务可由其他应用组件启动(如Activity),服务一旦被启动将在后台一直运行,即使启动服务的组件(Activity)已销毁也不受影响。 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。 例如,服务可以处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序交互,而所有这一切均可在后台进行。 Service基类定义了不同的回调方法,这边只介绍几种: MainActivity: MainService: 布局文件:前言
轨迹球
功能实现:
2.我这边用了名字缩写代替轨迹球;原理:
关于安卓监听器:
实现代码:
// An highlighted block public class MainActivity extends AppCompatActivity { private int screenW; private int screenH; public LinearLayout linearLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); linearLayout = (LinearLayout) findViewById(R.id.root); linearLayout.addView(new MyView(this)); } class MyView extends View { private Paint paint; private float cx = 50; private float cy = 50; public MyView(Context context) { super(context); initPaint(); } private void initPaint(){ paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.BLACK); paint.setTextSize(40); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); canvas.drawText("cc",cx,cy,paint); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 按下 cx = (int) event.getX(); cy = (int) event.getY(); // 通知重绘 postInvalidate(); break; case MotionEvent.ACTION_MOVE: // 移动 cx = (int) event.getX(); cy = (int) event.getY(); // 通知重绘 postInvalidate(); break; case MotionEvent.ACTION_UP: // 抬起 cx = (int) event.getX(); cy = (int) event.getY(); // 通知重绘 postInvalidate(); break; } return true; } } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/root" android:orientation="vertical" > </LinearLayout>
功能演示
注意事项:
Service实现简单的播放器
功能实现:
2.加入拖拽进度条功能,通过拖拽控制播放进度。Service概述:
菜鸟教程中有更为详细的介绍及具体操作例子,菜鸟链接:
Android :Service.回调方法:
方法
描述
onBind
当其他组件想要通过bindService()来绑定服务时,系统调用该方法。如果你实现该方法,你需要返回IBinder对象来提供一个接口,以便客户来与服务通信。你必须实现该方法,如果你不允许绑定,则直接返回null。
onCreate()
当服务通过onStartCommand()和onBind()被第一次创建的时候,系统调用该方法。该调用要求执行一次性安装。
实现代码:
public class MainActivity extends Activity implements View.OnClickListener { SeekBar seekBar; TextView curTime,totalTime; TextView title; private ServiceConnection sc; private MusicService ms; private boolean isStop; private double totalTimeInt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); IntentFilter filter = new IntentFilter(MusicService.MFILTER); registerReceiver(new MusicReceiver(),filter); sc = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub ms = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub ms = ((MusicService.MBinder)service).getService();//1 } }; Button previous = (Button) findViewById(R.id.previous); Button next = (Button) findViewById(R.id.next); Button stop = (Button) findViewById(R.id.stop); Button stopService = (Button) findViewById(R.id.stopService); seekBar = (SeekBar) findViewById(R.id.mSeekbar); curTime = (TextView) findViewById(R.id.curTime); totalTime = (TextView) findViewById(R.id.totalTime); title = (TextView) findViewById(R.id.title); previous.setOnClickListener(this); next.setOnClickListener(this); stop.setOnClickListener(this); stopService.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.previous: ms.playPrevious(); break; case R.id.next: ms.playNext(); break; case R.id.stop: if (isStop) { ms.restart(); } else { ms.parse(); } isStop = !isStop; break; case R.id.stopService: Intent intent = new Intent(MainActivity.this,MusicService.class); unbindService(sc); stopService(intent); break; default: break; } } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); Intent intent = new Intent(MainActivity.this,MusicService.class); intent.setPackage(getPackageName()); bindService(intent,sc, Context.BIND_AUTO_CREATE); //startService(intent); } private String transferMilliToTime(int millis){ DateFormat format = new SimpleDateFormat("mm:ss"); String result = format.format(new Date(millis)); return result; } private class MusicReceiver extends BroadcastReceiver {//3 @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if (intent.getIntExtra(MusicService.CURTIME,0)!=0) { double curTimeInt = intent.getIntExtra(MusicService.CURTIME,0); curTime.setText(transferMilliToTime((int)curTimeInt)); double result = curTimeInt/totalTimeInt*100; seekBar.setProgress((int) Math.floor(result)); } else if(intent.getIntExtra(MusicService.TOTALTIME,0)!=0) { totalTimeInt = intent.getIntExtra(MusicService.TOTALTIME,0); totalTime.setText(transferMilliToTime((int)(totalTimeInt))); } else if (!TextUtils.isEmpty(intent.getStringExtra(MusicService.NAME))) { title.setText(intent.getStringExtra(MusicService.NAME)); } } } }
public class MusicService extends Service { private List<File> musicList; private MediaPlayer player; private int curPage; public static final String MFILTER = "broadcast.intent.action.text"; public static final String NAME = "name"; public static final String TOTALTIME = "totaltime"; public static final String CURTIME = "curtime"; @Override public IBinder onBind(Intent intent) {//1 // TODO Auto-generated method stub return (IBinder) new MBinder(); } public class MBinder extends Binder {//2 public MusicService getService(){ return MusicService.this; } public MediaPlayer getPlayer(){ return player; } } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); musicList = new ArrayList<File>(); fillMusicList(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)); player = new MediaPlayer(); if (musicList.size() != 0) { startPlay(); } player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // TODO Auto-generated method stub player.reset(); curPage = curPage==musicList.size()-1? (curPage+1)%musicList.size() : curPage+1; startPlay(); } }); } /*迭代获取 音乐 文件*/ private void fillMusicList(File dir){ File[] sourceFiles = dir.listFiles(); for(File file : sourceFiles){ if (file.isFile() && file.getName().endsWith(".mp3")) musicList.add(file); else if (file.isDirectory()) fillMusicList(file); } } private void startPlay(){ if(musicList.size()!=0) { mSendBroadCast(NAME, musicList.get(curPage).getName());//4 try { player.setDataSource(musicList.get(curPage).getAbsolutePath()); player.prepare(); player.start(); player.getDuration(); mSendBroadCast(TOTALTIME, player.getDuration()); Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { // TODO Auto-generated method stub mSendBroadCast(CURTIME, player.getCurrentPosition()); } }, 0, 1000); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void playNext(){ curPage = curPage==musicList.size()-1? (curPage+1)%musicList.size() : curPage+1; Log.d("curpage",String.valueOf(curPage)); player.reset(); startPlay(); } public void playPrevious(){ curPage = curPage==0? 0 : curPage-1; Log.d("curpage",String.valueOf(curPage)); player.reset(); startPlay(); } public void parse(){ player.pause(); } public void restart(){ player.start(); } private void mSendBroadCast(String key, String value){ Intent intent = new Intent(MFILTER); intent.putExtra(key,value); sendBroadcast(intent); } private void mSendBroadCast(String key, int value){ Intent intent = new Intent(MFILTER); intent.putExtra(key,value); sendBroadcast(intent); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.capricorn.musicplayer.MainActivity"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:textSize="25sp" android:textColor="#444444" /> <SeekBar android:id="@+id/mSeekbar" android:layout_gravity="center_horizontal" android:layout_width="400dp" android:layout_height="wrap_content" android:max="100" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/curTime" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_alignParentLeft="true" /> <TextView android:id="@+id/totalTime" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_alignParentRight="true" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/previous" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="上一曲" android:onClick="previous" android:layout_alignParentLeft="true" /> <Button android:id="@+id/stop" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="停止音乐" android:layout_toRightOf="@id/previous" /> <Button android:id="@+id/next" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="下一曲" android:layout_alignParentRight="true" /> <Button android:id="@+id/stopService" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="停止音乐服务" android:layout_toLeftOf="@id/next" /> </RelativeLayout> </LinearLayout>
功能演示:
作者:石超超
参考链接: https://blog.csdn.net/qq_41939302/article/details/84719033.
原文地址: https://blog.csdn.net/ccbuhuidaima/article/details/106651239.
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算