2017-07-22 46 views
1

对于没有代码表示真诚的歉意,我要去参加婚礼,它是邮政编码或解释我的情况。Recycler Adapter上的Non Recycler Fragment调用方法?这甚至有可能吗?

我已经搜索过Stack并查看Recycler Adapter to Fragment(创建适配器)接口的许多帖子。

Fragment的一小部分(创建适配器)到适配器的帖子,但他们几乎不清楚。

我的情况是这样的:

在主要活动,当应用程序正在运行:

1)片段歌词(创建循环机适配器,它被设置成一个抒情回收站视图)

2)片段麦克风(语音识别麦克风功能和XML图标)。

我希望发生的是:

用户激活麦克风,能讲,那得到的数据传递到适配器的Java文件,并激活方法上适配器,造成对视觉变化RecyclerView Viewholder屏幕。

是的,我知道这可能是坏的体系结构。这是一个学校项目,我正在学习,而且我已经没有时间了。

*什么我可以迄今做*

我已经激活了预先制作的OnClick listerner的适配器(当在查看用户点击)和OnScroll为RecyclerView(用户滚动,它触发适配器中导致当前视图更改的方法)。

我已经为Microphone Fragment中的Passing Speech数据通过主要活动传递给Lyrics Fragment。

在Main上,我只是创建Lyrics Fragment的一个实例,然后在Lyrics Fragment上调用一个自定义方法来获取语音数据。像这样的东西。

LyricsFragment.TakeSpeechData(speech data);

*什么我的计划是...... *

当语音数据的歌词分段到来时,我以为我可以只写类似:

MyRecyclerAdapter.SomeMethodOnAdapter (speech data);

我现在可以免费入住。

它不工作

没有去。我在这里得到一个空指针异常。方法调用的MyRecyclerAdapter部分为null。我已经看过,不知道如何解决它。

我假设我引用原始适配器时创建的碎片放下RecyclerView并设置所有内容。这是Fragment Lyrics上的适配器的全局变量,我假设它“继续存在”。

我敢肯定我对基本的Java原则缺少了解,但我不知道该怎么做。

我已经花了数小时在这尝试,阅读,研究。我完全陷入困境。请帮忙。

编辑:这里是我的代码VerseFragment(我指的是作为“歌词”片段在我的文章)。注意这个片段是在屏幕上用recyclerView加载,创建和运行的。在用户使用也在屏幕上的micrphone片段之前,这已经创建。

public class VersesList extends Fragment { 
    @BindView(R.id.versesRecycleView) RecyclerView versesRecycleView; 
    @BindView(R.id.songNameTextView) TextView songName; 
    @BindView(R.id.artistTextView)TextView artistName; 
    private SharedPreferences mSharedPreferences; 
    LinearLayoutManager llm; 
    List verseList; 
    List finalModVerseList; 
    public VerseAdapter verseAdapter; 
    // temporary 
    private SharedPreferences.Editor editor; 
    public VersesList() { 
     // Required empty public constructor 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     // Inflate the layout for this fragment 

     View view = inflater.inflate(R.layout.fragment_verses_list, container, false); 
     ButterKnife.bind(this, view); 
     mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
     editor=mSharedPreferences.edit(); 
     displayArtistAndSongName(); 
     lyricsToVerseList(); 
     setVersesIntoRecyclerView(); 
     setVersesScrollListener(); 
     //temp 
     storeAllVerseLevels(); 
     return view; 
    } 

    public static VersesList newInstance(String lyrics){ 
     VersesList versesListFragment = new VersesList(); 
     Bundle args = new Bundle(); 
     args.putString("lyrics", lyrics); 
     versesListFragment.setArguments(args); 
     return versesListFragment; 

    } 

    public void lyricsToVerseList(){ 
     String lyrics = getArguments().getString("lyrics", ""); 
     verseList = new ArrayList<String>(); 
     finalModVerseList = new ArrayList<String>(); 
     verseList= Arrays.asList(lyrics.split("\n")); 
     int endOfFinalList=verseList.indexOf("..."); 
     for (int i = 0; i < endOfFinalList; i++) { 
      if(!verseList.get(i).toString().equals("")){ 
       String addThisVerse = verseList.get(i).toString(); 
       //check on length of verse, if too short add next, check again 
       int numberOfWords = addThisVerse.split(" ").length; 
       while (numberOfWords < 10 && i < endOfFinalList) { 
        i++; 
        addThisVerse += " " + verseList.get(i).toString(); 
        numberOfWords = addThisVerse.split(" ").length; 
       } 
       finalModVerseList.add(addThisVerse); 
      } 
     } 
    } 

    public void displayArtistAndSongName(){ 
     String song = '"'+mSharedPreferences.getString(SONG_NAME, null)+'"'; 
     String artist = "by "+mSharedPreferences.getString(ARTIST_NAME, null); 
     songName.setText(song); 
     artistName.setText(artist); 
    } 

    public void setVersesIntoRecyclerView(){ 
     verseAdapter = new VerseAdapter(finalModVerseList, (MainActivity)getActivity(), versesRecycleView); 
     versesRecycleView.setAdapter(verseAdapter); 
     llm = new LinearLayoutManager(getActivity(),LinearLayoutManager.HORIZONTAL, false); 
     versesRecycleView.setLayoutManager(llm); 
     PagerSnapHelper helper = new PagerSnapHelper(); 
     helper.attachToRecyclerView(versesRecycleView); 
    } 

    private void storeLevel(int indexNumber) { 
     editor.putInt(String.valueOf(indexNumber), 1).apply(); 
    } 

    private void storeAllVerseLevels(){ 
     for (int i=0; i< finalModVerseList.size();i++){ 
      storeLevel(i); 
     } 
     for (int j=0; j< finalModVerseList.size();j++){ 
      String level = String.valueOf(mSharedPreferences.getInt(String.valueOf(j), -1)); 
      Log.d("In Shared Preferences ", "Verse "+j+" Level "+level); 
     } 
    } 

    public void checkSpeech(String text){ 
     List<String> temp = new ArrayList<>(); 
     temp.add("test"); 

     VerseAdapter adapter = new VerseAdapter(temp, (MainActivity)getActivity(), versesRecycleView); 
     try { 
      adapter.resetVerse(); 
     }catch (NullPointerException e){ 
      Log.d("Null", e.toString()); 
     } 
    } 

    public void setVersesScrollListener(){ 
     versesRecycleView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
      @Override 
      public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
       super.onScrollStateChanged(recyclerView, newState); 

       if (newState == 0) { 
        verseAdapter.resetVerse(); 
       } 
      } 

      @Override 
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
       super.onScrolled(recyclerView, dx, dy); 
      } 
     }); 
    } 
} 

当你调用从您的适配器方法,是MyRecyclerAdapter实例或类?要拨打someMethodOnAdpater(speechData),您必须使用实例。夏正在使用一个实例。

如果您需要从创建它的片段中调用适配器方法,可以将其存储在像这样的变量中。

MyRecyclerAdapter adapter; 

@Override 
public View onCreateView(...) { 
    ... 
    adapter = new MyRecyclerAdapter(); 
    myRecyclerView.setAdapter(adapter); 
    ... 
} 

public void takeSpeechData(String data) { 
    adapter.someMethodAdapter(data); 
} 

编辑:

我不知道为什么你的recyclerview使用相同的适配器被设置后空。调用适配器绝对有可能(I tested a basic example)。不过,我的示例中的代码与您之前所说的代码没有什么不同。我已提高您的问题的知名度。

**编辑:添加麦克风片段,它具有接口**

package com.blueoxgym.javainthedark.Fragments; 


/** 
* A simple {@link Fragment} subclass. 
*/ 
public class MicFragment extends Fragment implements View.OnClickListener { 
    @BindView(R.id.progressBarMic) 
    ProgressBar micLevels; 
    @BindView(R.id.btn_mic) 
    ImageButton btnMicrophone; 
    private SpeechRecognizer speech = null; 
    private Intent recognizerIntent; 
    public final static String TAG = "In speech mode"; 
    public FragmentManager fragmentManager; 
    private SharedPreferences mSharedPreferences; 
    private SharedPreferences.Editor mEditor; 
    private String trackName; 
    private String artistName; 
    private CallMainLoadVerseFragment loadVerseFragment; 
    private CheckSpeech checkSpeechOnVerse; 


    public MicFragment() { 
     // Required empty public constructor 
    } 

    public static MicFragment newInstance(){ 
     MicFragment micFragment = new MicFragment(); 
     return micFragment; 
    } 


    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     // Inflate the layout for this fragment 
     View view = inflater.inflate(R.layout.fragment_mic, container, false); 
     ButterKnife.bind(this, view); 
     this.loadVerseFragment = (CallMainLoadVerseFragment) getActivity(); 
     this.checkSpeechOnVerse = (CheckSpeech) getActivity(); 
     btnMicrophone.setOnClickListener(this); 
     fragmentManager = getFragmentManager(); 
     mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
     mEditor = mSharedPreferences.edit(); 
     return view; 
    } 

    @Override 
    public void onClick(View v) { 
     if (v == btnMicrophone) { 
      startSpeechToText(); 
     } 

    } 

    class listener implements RecognitionListener { 
     ... 


    @Override 
     public void onResults(Bundle results) { 
      String str = new String(); 
      Log.d(TAG, "onResults " + results); 
      ArrayList<String> data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); 
      String text = data.get(0).toLowerCase().replace("by",""); 
      Fragment currentFragment = fragmentManager.findFragmentById(R.id.content_frame); 
      if (currentFragment.toString().contains("LyricSearch")){ 
       searchForSong(text); 
      } else if (currentFragment.toString().contains("VersesList")){ 
-----------> Here it is called checkSpeechOnVerse.checkingSpeech(text); 
      } 

     } 

    } 

    public void startSpeechToText(){ 
     btnMicrophone.setBackgroundResource(R.drawable.circle_green); 
     speech=SpeechRecognizer.createSpeechRecognizer(getContext()); 
     speech.setRecognitionListener(new listener()); 
     recognizerIntent= new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); 
     recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en-US"); 
     recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getActivity().getPackageName()); 
     recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); 
     recognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5); 
     speech.startListening(recognizerIntent); 
    } 

... 
... 

    public interface CheckSpeech { 
     void checkingSpeech (String text); 
    } 
} 

MainActivity,实现CheckSpeech接口

public class MainActivity extends AppCompatActivity 
     implements NavigationView.OnNavigationItemSelectedListener, MicFragment.CallMainLoadVerseFragment, MicFragment.CheckSpeech { 
.... 
... 
@Override 
    public void checkingSpeech(String text) { 
     VersesList versesList = new VersesList(); 
--------> Now, I'm pass data from Main to VersesList Fragment(it has the original Adapter)  
    versesList.checkSpeech(text); 
    } 

VersesList片段,在这里我打电话适配器

public class VersesList extends Fragment { 
    .... 
     private VerseAdapter verseAdapter; 
setVersesIntoRecyclerView(); 
.... 
<---ADAPTER IS MADE AND SET HERE----. 
public void setVersesIntoRecyclerView(){ 
     verseAdapter = new VerseAdapter(finalModVerseList, (MainActivity)getActivity(), versesRecycleView); 
     versesRecycleView.setAdapter(verseAdapter); 
     llm = new LinearLayoutManager(getActivity(),LinearLayoutManager.HORIZONTAL, false); 
     versesRecycleView.setLayoutManager(llm); 
     PagerSnapHelper helper = new PagerSnapHelper(); 
     helper.attachToRecyclerView(versesRecycleView); 
    } 


public void checkSpeech(String text){ 
-------> NPE NPE 
versesAdapter.someMethodOnAdapter(text); 

    } 

    public void setVersesScrollListener(){ 
     versesRecycleView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
      @Override 
      public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
       super.onScrollStateChanged(recyclerView, newState); 

       if (newState == 0) { 
BUT THIS WORKS!!! No NPE. --------> verseAdapter.resetVerse(); 

       } 
      } 

      @Override 
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
       super.onScrolled(recyclerView, dx, dy); 
//    VerseAdapter.VerseViewHolder view = versesRecycleView.findViewHolderForAdapterPosition(llm.findFirstVisibleItemPosition()); 
      } 
     }); 
    } 
+0

在'checkSpeech()',你为什么要创建一个新的适配器? –

+1

在checkingSpeech()中,您将实例化一个新的片段,但不会替换原始片段。该片段已创建,但未添加到容器中。如果您打算替换原始片段,则必须创建另一个事务,并用'transaction.replace(containerID,newFragment)' –

+0

来替换容器。如果您想使用相同的片段,则可以像访问VersesList片段=(VersesList)FragmentManager.findFragmentById(containerId).' –

回答

0

如果您需要从创建它的片段中调用适配器方法,则可以将其存储在该片段中的变量中。

MyRecyclerAdapter adapter; 

@Override 
public View onCreateView(...) { 
    ... 
    adapter = new MyRecyclerAdapter(); 
    myRecyclerView.setAdapter(adapter); 
    ... 
} 

public void takeSpeechData(String data) { 
    adapter.someMethodAdapter(data); 
} 

然后,您可以直接从另一个片段调用该方法。 (link to accessing fragments)

VersesList versesList = (VersesList) getActivity().getSupportFragmentManager.findFragmentById(containerId); 
versesList.takeSpeechData("data"); 

gif of example

+0

感谢亚当您的回应。我打电话给一个实例。它的设置与您的设置完全相同。这一连串事件现在就是这样。 Mic片段,语音发生(此时,屏幕上已经存在Verse片段,并且回收器视图处于活动状态并且功能正常),然后语音数据通过接口传递给MainActivity,其中接口方法触发对Verse上方法的调用分段。诗歌现在有数据。 On Verse Fragment,我的适配器已经实例化,设置为变量,在用户使用麦克风之前设置为recyclerview视图。 – Xia

+0

我已将代码发布到具有适配器的Fragment。 – Xia

+0

在'checkSpeech()'中,为什么要创建一个新的适配器? –