1

Firebaseを使用してデータを保存および取得するアプリケーションを作成しています。私はDBのためのデータを取得するとき、私はそれをListViewにフラグメントで表示している。次に、リスト内のある要素をクリックして、詳細フラグメントを開きます。 今、私はDBからの事前定義ノードからのデータのみを表示できますが、私がクリックした要素からのデータを表示したいと思います。これを行うには、ノード固有のキーを抽出し、他のフラグメントに解析する必要があるため、選択したノードのデータが表示されることがあります。しかし、私はこれを行う方法がわからないのですか?手伝って頂けますか?ここでリストビューでクリックしたFirebase要素から情報を取得します

は私のDB構造の画像です:

enter image description here

は「歌は、」DBの最初の子であり、それは-Lです - ***** ...私が欲しいのキーは、抽出する。ここ

つに送信し、データベースから検索されるSongData素子用コードである:ここ

public class SongData implements Serializable { 

private String songTitel; 
private String songArtist; 
private String songLanguage; 
private String songCode; 
private String intentAction; 
private int resultCode; 

    public SongData(){ } 

public SongData(String songTitel, String songArtist){ 

    this.songTitel = songTitel; 
    this.songArtist = songArtist; 
} 

public SongData(String songTitel, String songArtist, String songLanguages, String songCode){ 

    this.songTitel = songTitel; 
    this.songArtist = songArtist; 
    this.songLanguage = songLanguages; 
    this.songCode = songCode; 
} 

public String getSongTitel() { 
    return songTitel; 
} 
public void setSongTitel(String songTitel) { 
    this.songTitel = songTitel; 
} 

public String getSongArtist() { 
    return songArtist; 
} 
public void setSongArtist(String songArtist) { 
    this.songArtist = songArtist; 
} 

public String getSongLanguage() { 
    return songLanguage; 
} 
public void setSongLanguage(String songLanguage) { 
    this.songLanguage = songLanguage; 
} 

public String getSongCode() { 
    return songCode; 
} 
public void setSongCode(String songCode) { 
    this.songCode = songCode; 
} 

public String getIntentAction() { 
    return intentAction; 
} 

public int getResultCode() { 
    return resultCode; 
} 

@Override 
public String toString() { 
    return "SONG TITLE :" + this.songTitel + "\n SONG ARTIST :" + 
    this.songArtist; 
} 
    } 

リストビュー内のデータを表示するアクティビティからコード:

public class SearchFragment extends Fragment { 
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER 
private static final String ARG_SONG_TITLE = "song title"; 
private static final String ARG_SECTION_ID = "section_id"; 

private String mSongTitle; //mParam1 
private Button btnSearch; 
private TextView txtViewSearch; 
private EditText editTextSearch; 
private ListView listViewSearch; 
private SearchAdaptor searchAdaptor; 

//For storing list of songs from DB 
private ArrayList<String> songArrayList = new ArrayList<>(); 

private OnFragmentSearchInteractionListener mListener; 

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

/** 
* Use this factory method to create a new instance of 
* this fragment using the provided parameters. 
* 
* @param songTitle Parameter 1. 
* @return A new instance of fragment SearchFragment. 
*/ 
// TODO: Rename and change types and number of parameters 
public static SearchFragment newInstance(String songTitle) { 
    SearchFragment fragment = new SearchFragment(); 
    Bundle args = new Bundle(); 
    args.putString(ARG_SONG_TITLE, songTitle); 
    fragment.setArguments(args); 
    return fragment; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (getArguments() != null) { 
     mSongTitle = getArguments().getString(ARG_SONG_TITLE); 
    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View view = inflater.inflate(R.layout.fragment_search, container, false); 

    //Find elements from view 
    btnSearch = (Button) view.findViewById(R.id.btnSearch); 
    txtViewSearch = (TextView) view.findViewById(R.id.txtViewSearch); 
    editTextSearch = (EditText) view.findViewById(R.id.editTxtSearch); 
    listViewSearch = (ListView) view.findViewById(R.id.listViewSearch); 

    //Array adapter for Array List with songs 
    final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, songArrayList); 
    listViewSearch.setAdapter(arrayAdapter); 

    FirebaseDatabase database = FirebaseDatabase.getInstance(); 
    DatabaseReference songRef = database.getReference("Song"); 

    songRef.addChildEventListener(new ChildEventListener() { 
     @Override 
     public void onChildAdded(DataSnapshot dataSnapshot, String s) { 

      SongData song = (SongData) dataSnapshot.getValue(SongData.class); 
      String songString = String.valueOf(song); 
      songArrayList.add(songString); 
      arrayAdapter.notifyDataSetChanged(); 

     } 

     @Override 
     public void onChildChanged(DataSnapshot dataSnapshot, String s) { 
       //Required 
     } 

     @Override 
     public void onChildRemoved(DataSnapshot dataSnapshot) { 

      songArrayList.remove(dataSnapshot.getValue(SongData.class)); 
      arrayAdapter.notifyDataSetChanged(); 

     } 

     @Override 
     public void onChildMoved(DataSnapshot dataSnapshot, String s) { 
       //Required 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 
       //Required 
     } 
    }); 

    listViewSearch.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long Id) { 
      //position is the index of the item, counts from 0 
      //Reference: https://stackoverflow.com/questions/21028786/how-do-i-open-a-new-fragment-from-another-fragment 
      SongDetailsFragment songDetailsFragment = new SongDetailsFragment(); 
      getActivity().getSupportFragmentManager().beginTransaction() 
        .replace(R.id.fragment_placeholder, songDetailsFragment,"findThisFragment") 
        .addToBackStack(null) 
        .commit(); 
     } 
    }); 

    return view; 
} 

@Override 
public void onResume() { 
    super.onResume(); 

    // Refresh the state of the +1 button each time the activity receives focus. 
    /////btnSearch.initialize(PLUS_ONE_URL, PLUS_ONE_REQUEST_CODE); 
} 

// TODO: Rename method, update argument and hook method into UI event 
public void onButtonPressed(Uri uri) { 
    if (mListener != null) { 
     mListener.onFragmentInteraction(uri); 
    } 
} 

@Override 
public void onAttach(Context context) { 
    super.onAttach(context); 
    if (context instanceof OnFragmentSearchInteractionListener) { 
     mListener = (OnFragmentSearchInteractionListener) context; 
    } else { 
     throw new RuntimeException(context.toString() 
       + " must implement OnFragmentSearchInteractionListener"); 
    } 
} 

@Override 
public void onDetach() { 
    super.onDetach(); 
    mListener = null; 
} 

/** 
* This interface must be implemented by activities that contain this 
* fragment to allow an interaction in this fragment to be communicated 
* to the activity and potentially other fragments contained in that 
* activity. 
* <p> 
* See the Android Training lesson <a href= 
* "http://developer.android.com/training/basics/fragments/communicating.html" 
* >Communicating with Other Fragments</a> for more information. 
*/ 
public interface OnFragmentSearchInteractionListener { 
    // TODO: Update argument type and name 
    void onFragmentInteraction(Uri uri); 
} 

    } 
詳細表示するフラグメントのための

コード:私はここで誰かを願っています

public class SongDetailsFragment extends Fragment { 
// TODO: Rename parameter arguments, choose names that match 
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER 
private static final String ARG_PARAM1 = "param1"; 
private static final String ARG_PARAM2 = "param2"; 
// The request code must be 0 or greater. 
private static final int PLUS_ONE_REQUEST_CODE = 0; 
// The URL to +1. Must be a valid URL. 
private final String PLUS_ONE_URL = "http://developer.android.com"; 
// TODO: Rename and change types of parameters 
private String mParam1; 
private String mParam2; 
private PlusOneButton mPlusOneButton; 

private OnSongDetailsFragmentInteractionListener mListener; 

private TextView txtViewShowSongTitel; 
private TextView txtViewShowSongArtist; 
private TextView txtViewShowSongLanguage; 
private TextView txtViewShowSongCode; 

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

/** 
* Use this factory method to create a new instance of 
* this fragment using the provided parameters. 
* 
* @param param1 Parameter 1 
* @return A new instance of fragment SongDetailsFragment. 
*/ 
// TODO: Rename and change types and number of parameters 
public static SongDetailsFragment newInstance(String param1) { 
    SongDetailsFragment fragment = new SongDetailsFragment(); 
    Bundle args = new Bundle(); 
    args.putString(ARG_PARAM1, param1); 
    fragment.setArguments(args); 
    return fragment; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (getArguments() != null) { 
     mParam1 = getArguments().getString(ARG_PARAM1); 
     mParam2 = getArguments().getString(ARG_PARAM2); 
    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View view = inflater.inflate(R.layout.fragment_song_details, container, false); 

    final TextView txtViewShowSongTitel = (TextView) view.findViewById(R.id.TxtViewShowSongTitel); 
    final TextView txtViewShowSongArtist = (TextView) view.findViewById(R.id.TxtViewShowSongArtist); 
    final TextView txtViewShowSongLanguage = (TextView) view.findViewById(R.id.TxtViewShowSongLanguage); 
    final TextView txtViewShowSongCode = (TextView) view.findViewById(R.id.TxtViewShowSongCode); 

    // Reference: https://firebase.google.com/docs/database/android/read-and-write 
    //Retrieve data for the Firebase Database 
    FirebaseDatabase database = FirebaseDatabase.getInstance(); 
    DatabaseReference songRef = database.getReference("Song").child("-L-qBD0S742-EQkVvers"); 

    songRef.addValueEventListener(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 

      SongData s = dataSnapshot.getValue(SongData.class); 

      txtViewShowSongTitel.setText(s.getSongTitel()); 
      txtViewShowSongArtist.setText(s.getSongArtist()); 
      txtViewShowSongLanguage.setText(s.getSongLanguage()); 
      txtViewShowSongCode.setText(s.getSongCode()); 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

      // Getting songData failed, log a message 
      Log.w(TAG, "loadSong:onCancelled", databaseError.toException()); 
     } 
    }); 

    Button btnOK = (Button) view.findViewById(R.id.btnOK); 
    btnOK.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 

      //Close SongDetailsFragment and return to previous fragment 
      getActivity().onBackPressed(); 
     } 

    }); 

    return view; 
} 

@Override 
public void onResume() { 
    super.onResume(); 

    // Refresh the state of the +1 button each time the activity receives focus. 
    //mPlusOneButton.initialize(PLUS_ONE_URL, PLUS_ONE_REQUEST_CODE); 
} 

// TODO: Rename method, update argument and hook method into UI event 
public void onButtonPressed(Uri uri) { 
    if (mListener != null) { 
     mListener.onFragmentInteraction(uri); 
    } 
} 

/*@Override 
public void onAttach(Context context) { 
    super.onAttach(context); 
    if (context instanceof OnSongDetailsFragmentInteractionListener) { 
     mListener = (OnSongDetailsFragmentInteractionListener) context; 
    } else { 
     throw new RuntimeException(context.toString() 
       + " must implement OnSongDetailsFragmentInteractionListener"); 
    } 
}*/ 

@Override 
public void onDetach() { 
    super.onDetach(); 
    mListener = null; 
} 

/** 
* This interface must be implemented by activities that contain this 
* fragment to allow an interaction in this fragment to be communicated 
* to the activity and potentially other fragments contained in that 
* activity. 
* <p> 
* See the Android Training lesson <a href= 
* "http://developer.android.com/training/basics/fragments/communicating.html" 
* >Communicating with Other Fragments</a> for more information. 
*/ 
public interface OnSongDetailsFragmentInteractionListener { 
    // TODO: Update argument type and name 
    void onFragmentInteraction(Uri uri); 
} 

    } 

をCA私を助けて!

+0

リストのIDをFragmentに渡すには、そこに 'SongDetailsFragment.newInstance(" - L -... ")'を使用する必要があります。 –

答えて

1

@Excludeアノテーションを使用してSongDataクラスのソングキーを格納する新しいStringフィールドを追加します。 Excludeアノテーションは、データの保存/取得時にAnnotatedフィールドをスキップするようFirebaseに指示します。あなたのonChildAddedコールバックで

@Exclude 
private String key; 

public void getKey(){this.key;} 
public void setKey(final String key){this.key = key;} 
.... 

、DataSnapshotからキーをつかむと、あなたのSongDataオブジェクトに保存します。

@Override 
public void onChildAdded(DataSnapshot dataSnapshot, String s) { 
     SongData song = (SongData) dataSnapshot.getValue(SongData.class); 
     song.setKey(dataSnapshot.getKey()); 
     String songString = String.valueOf(song); 
     songArrayList.add(songString); 
     arrayAdapter.notifyDataSetChanged(); 
    } 

今、あなたのようなインスタンスを作成することにより、選択したSongDataオブジェクトから自分のフラグメントへの曲のキーを渡すことができます:SongDetailFragment.newInstance(selectedSong.getKey())

編集: 以下@Alexマモで述べたように、あなたはまた、必要にFirebaseからすべての曲を取り出す。今は、単一のキーを指定しています。したがって、あなたは1つの曲だけを取得します。あなたのリストを構築するために彼の答えを組み込み、あなたの断片をインスタンス化してください。

+0

selectedSongを実装するにはどうすればよいですか?私は試しました 文字列selectedItem =(String)listViewSearch.getItemAtPosition(position); SongDetailsFragment songDetailsFragment1 = SongDetailsFragment.newInstance(selectedItem.getKey()); しかし、それは間違っているようです。私はonItemClick()でそれをやっています。 –

+0

OnListItemClickListenerで、アダプタ位置を使用して、対応するソングをSongData selectedSong = songArraylist.get(position)として取得します。今、あなたはすべての情報を持っていて、曲のIDで新しい断片をインスタンス化します。 – Puneet

+0

私は言ってみました: 'View parentRow =(View)view.getParent(); ListView listView =(ListView)parentRow.getParent(); position = listView.getPositionForView(parentRow); long selectedSong = arrayAdapter.getItemId(position); SongDetailsFragment songDetailsFragment = new SongDetailsFragment(); songDetailsFragment.newInstance(selectedSong.dataSnapShot.getKey()); ' 私は間違っていますか? –

1

すべてのこれらのキーを取得するには、次のコードを使用してください:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); 
DatabaseReference songRef = rootRef.child("Song"); 
ValueEventListener eventListener = new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     for(DataSnapshot ds : dataSnapshot.getChildren()) { 
      String key = ds.getKey(); 
      Log.d("TAG", key); 
     } 
    } 

    @Override 
    public void onCancelled(DatabaseError databaseError) {} 
}; 
songRef.addListenerForSingleValueEvent(eventListener); 

出力は、それらの生成されたキーアルとなります。

+0

良いキャッチ。私はちょうど彼がFirebaseで適切に質問していると仮定しましたが、彼はただ一つの曲の情報を引っ張っていました。 – Puneet

関連する問題