代码之家  ›  专栏  ›  技术社区  ›  Rohit Sharma Bigyelow

recyclerview+mediaplayer+toggle按钮+string uri

  •  5
  • Rohit Sharma Bigyelow  · 技术社区  · 7 年前

    背景: 我正在开发一个健身应用程序。到目前为止一切都很好,但当我处理音频文件时出现了问题 MediaPlayer 在安卓系统中。

    我查了资源发现 ListView 但在RecyclerView+MediaPlayer上找不到任何内容。

    我想知道如何在使用recyclerview+toggle button+string uri(脱机-原始文件夹)时使其工作

    问题: 现在,它正在播放每个单击事件的第一个.mp3文件(对于eng: 原始样品 为印地语演奏: r.raw.sample_one_印地语 播放)。我认为它没有考虑内部立场。

    稍后,我想把它放到网上(可能是谷歌云),因为音频文件(.mp3)让我的应用程序变得相当沉重。任何关于这方面的想法都会很受欢迎(快速缓冲等)。

    listexercises.java语言

    public class ListExercises extends AppCompatActivity {
    
        List<ExerciseAudio> exerciseList = new ArrayList<>();
        RecyclerView.LayoutManager layoutManager;
        RecyclerView recyclerView;
        RecyclerViewAdapterAud adapter;
        PlayClickHandler clickHandler;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.list_exercises);
    
            initData();
    
            recyclerView = (RecyclerView) findViewById(R.id.list_ex);
            adapter = new RecyclerViewAdapterAud(exerciseList, getBaseContext());
            layoutManager = new LinearLayoutManager(this);
            recyclerView.setLayoutManager(layoutManager);
            recyclerView.setAdapter(adapter);
        }
    
        private void initData() {
    
            exerciseList.add(new ExerciseAudio(R.drawable.sample_one, "Sample Exercise One", "Sans One",
                    R.raw.sample_one_eng,
                    R.raw.sample_one_hindi));
    
            exerciseList.add(new ExerciseAudio(R.drawable.sample_two, "Sample Exercise Two", "Sans Two",
                    R.raw.sample_two_eng,
                    R.raw.sample_two_hindi));
    
            exerciseList.add(new ExerciseAudio(R.drawable.sample_three, "Sample Exercise Three", "Sans Three",
                    R.raw.sample_three_eng,
                    R.raw.sample_three_hindi));
    
            exerciseList.add(new ExerciseAudio(R.drawable.sample_four, "Sample Exercise Four", "Sans Four",
                    R.raw.sample_four_eng,
                    R.raw.sample_four_hindi));
        }
    }
    

    viewexercise.java视图

    public class ViewExercise extends AppCompatActivity {
    
        int image_id, eng_aud_url, hindi_aud_url;
        String name, sans_name;
    
        ArrayList<String> arrayList = new ArrayList<>();
    
        TextView timer, title, sansName;
        ImageView detail_image;
        ToggleButton tg_btn_speaker_eng, tg_btn_speaker_hindi;
    
        MediaPlayer mp;
    
        int position;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.view_exercise);
    
            Field[] field = R.raw.class.getFields();
            for (int i = 0; i < field.length; i++){
                arrayList.add(field[i].getName());
            }
    
            title = (TextView) findViewById(R.id.title);
            sansName = (TextView) findViewById(R.id.sans_name);
            detail_image = (ImageView) findViewById(R.id.detail_image);
    
            tg_btn_speaker_eng = (ToggleButton) findViewById(R.id.tg_btn_speaker_eng);
            tg_btn_speaker_hindi = (ToggleButton) findViewById(R.id.tg_btn_speaker_hindi);
    
            tg_btn_speaker_eng.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //toggleEnglish(tg_btn_speaker_eng.isChecked());
                    int positionEng = 0;
                    playSongEng(positionEng);
                }
            });
    
            tg_btn_speaker_hindi.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //toggleHindi(tg_btn_speaker_hindi.isChecked());
                    int positionHindi = 0;
                    playSongHindi(positionHindi);
                }
            });
    
            if (getIntent() != null) {
                image_id = getIntent().getIntExtra("image_id", -1);
                name = getIntent().getStringExtra("name");
                sans_name = getIntent().getStringExtra("sanskrit_name");
    
                detail_image.setImageResource(image_id);
                title.setText(name);
                sansName.setText(sans_name);
            }
        }
    
    
        public void playSongEng(int i) {
            //mp.reset();
            int resId = getResources().getIdentifier(arrayList.get(i), "raw", getPackageName());
            mp = MediaPlayer.create(getApplicationContext(), resId);
            mp.start();
        }
    
        public void playSongHindi(int i) {
            //mp.reset();
            int resId = getResources().getIdentifier(arrayList.get(i), "raw", getPackageName());
            mp = MediaPlayer.create(getApplicationContext(), resId);
            mp.start();
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (mp != null)
                mp.release();
        }
    }
    

    这就是它的样子!

    编辑(以避免混淆): 刚刚注意到,那个图像名 列出练习 而不是 查看练习 对应于 ListExercises.java

    List Exercise - RecyclerView

    这个对应于 ViewExercise.java

    View Exercise

    谢谢!

    3 回复  |  直到 7 年前
        1
  •  2
  •   Rohit Sharma Bigyelow    7 年前

    您还可以在内部设置单击侦听器 onBindViewHolder 通过在 项目练习 布局如下:

    holder.parentView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(context, ViewExercise.class);
                intent.putExtra("image_id", exerciseList.get(position).getImage_id());
                intent.putExtra("name", exerciseList.get(position).getName());
                intent.putExtra("sanskrit_name", exerciseList.get(position).getSanskrit_name());
                intent.putExtra("eng_aud_url", exerciseList.get(position).getEng_aud_url());
                intent.putExtra("hindi_aud_url", exerciseList.get(position).getHindi_aud_url());
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);
            }
        });
    

    或者你可以参考 here

    编辑- 要根据recyclerview列表的位置播放音频,我们必须将特定练习的原始文件名发送到媒体播放器。

    将两个新变量添加到 练习音频 模型类:

    private String file_name_eng;
    private String file_name_hindi;
    

    现在修改 初始数据 方法如下:

    private void initData() {
    
        exerciseList.add(new ExerciseAudio(R.drawable.sample_one, "Sample Exercise One", "Sans One",
                R.raw.sample_one_eng, R.raw.sample_one_hindi,
                "sample_one_eng", "sample_one_hindi"));
    
        exerciseList.add(new ExerciseAudio(R.drawable.sample_two, "Sample Exercise Two", "Sans Two",
                R.raw.sample_two_eng, R.raw.sample_two_hindi,
                "sample_two_eng", "sample_one_hindi"));
    
        exerciseList.add(new ExerciseAudio(R.drawable.sample_three, "Sample Exercise Three", "Sans Three",
                R.raw.sample_three_eng, R.raw.sample_three_hindi,
                "sample_three_eng", "sample_three_hindi"));
    
        exerciseList.add(new ExerciseAudio(R.drawable.sample_four, "Sample Exercise Four", "Sans Four",
                R.raw.sample_four_eng, R.raw.sample_four_hindi,
                "sample_four_eng", "sample_four_hindi"));
    }
    

    现在修改 视图练习 意图:

    intent.putExtra("file_name_eng", exerciseList.get(position).getFile_name_eng());
    intent.putExtra("file_name_hindi", exerciseList.get(position).getFile_name_hindi());
    

    把额外的字符串放进去 视图练习 活动并将其发送到 mediaplayer 以下内容:

    file_name_eng = getIntent().getStringExtra("file_name_eng");
    file_name_hindi = getIntent().getStringExtra("file_name_hindi");
    
    For english:
        int resId = getResources().getIdentifier(file_name_eng, "raw", getPackageName());
    
    For hindi:
        int resId = getResources().getIdentifier(file_name_hindi, "raw", getPackageName());
    
        2
  •  4
  •   Mobile Team ADR-Flutter    7 年前

    请尝试此代码.. 将下面的依赖项添加到应用程序级渐变文件中..

        compile 'com.google.android.exoplayer:exoplayer:r2.3.0'
    

    在那之后用下面的代码..

    public class VideoPlayerActivity extends AppCompatActivity implements ExoPlayer.EventListener {
    
    private SimpleExoPlayer mSimpleExoPlayer;
    
    private SimpleExoPlayerView mSimpleExoPlayerView;
    
    private Handler mMainHandler;
    private AdaptiveTrackSelection.Factory mAdaptiveTrackSelectionFactory;
    private TrackSelector mTrackSelector;
    private LoadControl mLoadControl;
    private DefaultBandwidthMeter mBandwidthMeter;
    private DataSource.Factory mDataSourceFactory;
    private SimpleCache mSimpleCache;
    private DataSource.Factory mFactory;
    private MediaSource mVideoSource;
    private LoopingMediaSource mLoopingMediaSource;
    private ProgressBar mProgressBar;
    private String videoUrl="http://sample.vodobox.net/skate_phantom_flex_4k/skate_phantom_flex_4k.m3u8";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video);
        mSimpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.videoPlayer);
        mProgressBar = (ProgressBar) findViewById(R.id.amPrgbrLoading);
    }
    
    /**
     * this method play audio and video with hls streaming.
     */
    private void playMedia() {
        mMainHandler = new Handler();
        mBandwidthMeter = new DefaultBandwidthMeter();
        mAdaptiveTrackSelectionFactory = new AdaptiveTrackSelection.Factory(mBandwidthMeter);
        mTrackSelector = new DefaultTrackSelector(mAdaptiveTrackSelectionFactory);
    
        mLoadControl = new DefaultLoadControl();
        mSimpleExoPlayer = ExoPlayerFactory.newSimpleInstance(this, mTrackSelector, mLoadControl);
    
        mSimpleExoPlayerView.setPlayer(mSimpleExoPlayer);
        mSimpleExoPlayerView.setControllerVisibilityListener(new PlaybackControlView.VisibilityListener() {
            @Override
            public void onVisibilityChange(int visibility) {
                mSimpleExoPlayerView.showController();
            }
        });
        mDataSourceFactory = new DefaultDataSourceFactory(this,Util.getUserAgent(this, "com.exoplayerdemo"), mBandwidthMeter);
        mSimpleCache = new SimpleCache(this.getCacheDir(), new LeastRecentlyUsedCacheEvictor(1024 * 1024 * 10));
        mFactory = new CacheDataSourceFactory(mSimpleCache, mDataSourceFactory,0);
        mVideoSource = new HlsMediaSource(Uri.parse(videoUrl),
                mFactory, mMainHandler, new AdaptiveMediaSourceEventListener() {
            @Override
            public void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs) {
                //Toast.makeText(VideoPlayerActivity.this, "Load Started", Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onLoadCompleted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
                //Toast.makeText(VideoPlayerActivity.this, "Load Completed", Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onLoadCanceled(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
    
            }
    
            @Override
            public void onLoadError(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) {
                videoUrl=""; // define second url
            }
    
            @Override
            public void onUpstreamDiscarded(int trackType, long mediaStartTimeMs, long mediaEndTimeMs) {
               // Toast.makeText(VideoPlayerActivity.this, "Up stream", Toast.LENGTH_SHORT).show();
            }
    
            @Override
            public void onDownstreamFormatChanged(int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaTimeMs) {
               // Toast.makeText(VideoPlayerActivity.this, "Down Stream", Toast.LENGTH_SHORT).show();
            }
        });
    
        mLoopingMediaSource = new LoopingMediaSource(mVideoSource);
        mSimpleExoPlayer.prepare(mLoopingMediaSource);
        mSimpleExoPlayer.setPlayWhenReady(true);
        mSimpleExoPlayer.addListener(new ExoPlayer.EventListener() {
            @Override
            public void onTimelineChanged(Timeline timeline, Object manifest) {
    
            }
    
            @Override
            public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
    
            }
    
            @Override
            public void onLoadingChanged(boolean isLoading) {
    
            }
    
            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    
                if (playbackState == ExoPlayer.STATE_BUFFERING) {
                    mProgressBar.setVisibility(View.VISIBLE);
                } else {
                    mProgressBar.setVisibility(View.GONE);
                }
    
            }
    
            @Override
            public void onPlayerError(ExoPlaybackException error) {
    
            }
    
            @Override
            public void onPositionDiscontinuity() {
    
            }
        });
    
    
    
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        playMedia();
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        stopMedia();
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        stopMedia();
    }
    
    private void stopMedia() {
        mSimpleExoPlayer.stop();
        mSimpleExoPlayer.release();
    }
    
    
    
    @Override
    public void onTimelineChanged(Timeline timeline, Object manifest) {
    
    }
    
    @Override
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
    
    }
    
    @Override
    public void onLoadingChanged(boolean isLoading) {
    
    }
    
    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    
    }
    
    @Override
    public void onPlayerError(ExoPlaybackException error) {
    
    }
    
    @Override
    public void onPositionDiscontinuity() {
    
    }
    

    }

    在这个用于视频的代码中,您可以传递您的音频文件路径。

    XML代码..

            <com.google.android.exoplayer2.ui.SimpleExoPlayerView
            android:id="@+id/videoPlayer"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
             />
    
        3
  •  2
  •   Rahul Shukla    7 年前

    您应该设计recycler view的viewholder,使其能够保存recycler视图工作所需的所有数据。例如

    ExcerciseViewHolder extends ViewHolder {
     public int uriEnglish;  //To be replaced by URL/URI later on
     public int uriHindi; //To be replaced by URL/URI later on
     public View englishButton;
     public View hindiButton;
    }
    

    您的活动应该以以下形式实现一个接口

    public interface PlayClickHandler {
    public playInstruction(int uriID);
    }
    

    适配器应该如下所示:

    public class ExerciseAdapter extends RecyclerView.Adapter<ExerciseViewHolder> {
        PlayClickHandler clickHandler;
        public ExerciseAdapter(PlayClickHandler clickHandler){
            this.clickHandler = clickHandler;
        }
        ...
        public onBindViewHolder(ExerciseViewHolder holder, int position) {
            final ExcerciseViewHolder finalHolder = holder;
            holder.hindiButton.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View v) {
               clickHandler.playInstruction(finalHolder.uriHindi);
               }
            })
        }
    }
    

    您的活动应该实现这个接口,并提供使用mediaplayer的单个实例进行回放的功能。

    遵循上述代码中的思想,我相信您应该能够实现您想要的目标。如果你对任何问题都不清楚,请尽管问。