2017-11-14 12 views
0

FirebaseUIコードを使用してlistviewアダプタを作成する。アダプタのgetView()は呼び出されず、何も表示されません。データを送信すると正常に動作しているようです。変更されたアダプタはgetView()を呼び出さない

import android.content.Context; 
import android.net.Uri; 
import android.os.Bundle; 
import android.support.design.widget.FloatingActionButton; 
import android.support.v4.app.Fragment; 
import android.text.format.DateFormat; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.EditText; 
import android.widget.ListView; 
import android.widget.TextView; 


import com.google.firebase.auth.FirebaseAuth; 
import com.google.firebase.database.FirebaseDatabase; 
import com.google.firebase.database.Query; 
import com.hqs.tart.adapters.firebase.FirebaseListAdapter; 
import com.hqs.tart.adapters.firebase.FirebaseListOptions; 
import com.hqs.tart.tabletoproleplaytool.R; 
import com.hqs.tart.models.ChatMessage; 

/** 
* A simple {@link Fragment} subclass. 
* Activities that contain this fragment must implement the 
* {@link GlobalChat.OnFragmentInteractionListener} interface 
* to handle interaction events. 
* Use the {@link GlobalChat#newInstance} factory method to 
* create an instance of this fragment. 
*/ 
public class GlobalChat 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"; 

    // TODO: Rename and change types of parameters 
    private String mParam1; 
    private String mParam2; 

    private OnFragmentInteractionListener mListener; 

    private FirebaseListAdapter<ChatMessage> adapter; 
    ListView listOfMessages; 

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

    /** 
    * Use this factory method to create a new instance of 
    * this fragment using the provided parameters. 
    * 
    * @param param1 Parameter 1. 
    * @param param2 Parameter 2. 
    * @return A new instance of fragment GlobalChat. 
    */ 
    // TODO: Rename and change types and number of parameters 
    public static GlobalChat newInstance(String param1, String param2) { 
     GlobalChat fragment = new GlobalChat(); 
     Bundle args = new Bundle(); 
     args.putString(ARG_PARAM1, param1); 
     args.putString(ARG_PARAM2, param2); 
     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); 
     } 

     Query query = FirebaseDatabase.getInstance() 
       .getReference() 
       .child("chats") 
       .limitToLast(50); 
     FirebaseListOptions<ChatMessage> options = new FirebaseListOptions.Builder<ChatMessage>() 
       .setQuery(query, ChatMessage.class) 
       .setLayout(R.layout.fragment_chat) 
       .build(); 

     /* adapter = new FirebaseListAdapter<ChatMessage>(options) {getActivity(), ChatMessage.class, 
       R.layout.fragment_chat, FirebaseDatabase.getInstance().getReference() */ 
     adapter = new FirebaseListAdapter<ChatMessage>(options) { 
      @Override 
      protected void populateView(View v, ChatMessage model, int position) { 
       // Get references to the views of message.xml 
       TextView messageText = (TextView) v.findViewById(R.id.message_text); 
       TextView messageUser = (TextView) v.findViewById(R.id.message_user); 
       TextView messageTime = (TextView) v.findViewById(R.id.message_time); 

       // Set their text 
       messageText.setText(model.getMessageText()); 
       messageUser.setText(model.getMessageUser()); 
       Log.d("getFirebaseMessage", model.getMessageText()); 

       // Format the date before showing it 
       messageTime.setText(DateFormat.format("dd-MM-yyyy (HH:mm:ss)", 
         model.getMessageTime())); 
      } 

     }; 
    } 

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

     //set OnClick listener for button 
     FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.fab); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       EditText input = (EditText) getActivity().findViewById(R.id.input_box); 

       // Read the input field and push a new instance 
       // of ChatMessage to the Firebase database 
       FirebaseDatabase.getInstance() 
         .getReference() 
         .child("chats") 
         .push() 
         .setValue(new ChatMessage(input.getText().toString(), 
           FirebaseAuth.getInstance() 
             .getCurrentUser() 
             .getDisplayName()) 
         ); 
       Log.d("setFirebaseMessage", input.getText().toString()); 

       // Clear the input 
       input.setText(""); 
       listOfMessages.setAdapter(adapter); 
      } 
     }); 

     listOfMessages = (ListView) view.findViewById(R.id.list_of_messages); 

     listOfMessages.setAdapter(adapter); 
     listOfMessages.setVisibility(View.VISIBLE); 

     return view; 
    } 

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

    @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 OnFragmentInteractionListener { 
     // TODO: Update argument type and name 
     void onFragmentInteraction(Uri uri); 
    } 
} 

GlobalChat.java

import android.arch.lifecycle.Lifecycle; 
import android.arch.lifecycle.LifecycleOwner; 
import android.arch.lifecycle.OnLifecycleEvent; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 

import com.google.firebase.database.DataSnapshot; 
import com.google.firebase.database.DatabaseError; 
import com.google.firebase.database.DatabaseReference; 
import com.hqs.tart.utils.firebase.ui.ChangeEventType; 

/** 
* This class is a generic way of backing an Android {@link android.widget.ListView} with a Firebase 
* location. It handles all of the child events at the given Firebase location. It marshals received 
* data into the given class type. 
* <p> 
* See the <a href="https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md">README</a> 
* for an in-depth tutorial on how to set up the FirebaseListAdapter. 
* 
* @param <T> The class type to use as a model for the data contained in the children of the given 
*   Firebase location 
*/ 
public abstract class FirebaseListAdapter<T> extends BaseAdapter implements FirebaseAdapter<T> { 
    private static final String TAG = "FirebaseListAdapter"; 

    private final ObservableSnapshotArray<T> mSnapshots; 
    protected final int mLayout; 

    public FirebaseListAdapter(FirebaseListOptions<T> options) { 
     mSnapshots = options.getSnapshots(); 
     mLayout = options.getLayout(); 

     if (options.getOwner() != null) { 
      options.getOwner().getLifecycle().addObserver(this); 
     } 
    } 

    @Override 
    @OnLifecycleEvent(Lifecycle.Event.ON_START) 
    public void startListening() { 
     if (!mSnapshots.isListening(this)) { 
      mSnapshots.addChangeEventListener(this); 
     } 
    } 

    @Override 
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP) 
    public void stopListening() { 
     mSnapshots.removeChangeEventListener(this); 
     notifyDataSetChanged(); 
    } 

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) 
    void cleanup(LifecycleOwner source) { 
     source.getLifecycle().removeObserver(this); 
    } 

    @Override 
    public void onChildChanged(ChangeEventType type, 
           DataSnapshot snapshot, 
           int newIndex, 
           int oldIndex) { 
     notifyDataSetChanged(); 
    } 

    @Override 
    public void onDataChanged() { 
    } 

    @Override 
    public void onError(DatabaseError error) { 
     Log.w(TAG, error.toException()); 
    } 

    @Override 
    public ObservableSnapshotArray<T> getSnapshots() { 
     return mSnapshots; 
    } 

    @Override 
    public T getItem(int position) { 
     return mSnapshots.get(position); 
    } 

    @Override 
    public DatabaseReference getRef(int position) { 
     return mSnapshots.getSnapshot(position).getRef(); 
    } 

    @Override 
    public int getCount() { 
     return mSnapshots.size(); 
    } 

    @Override 
    public long getItemId(int i) { 
     // http://stackoverflow.com/questions/5100071/whats-the-purpose-of-item-ids-in-android-listview-adapter 
     return mSnapshots.getSnapshot(i).getKey().hashCode(); 
    } 

    @Override 
    public View getView(int position, View view, ViewGroup viewGroup) { 
     if (view == null) { 
      view = LayoutInflater.from(viewGroup.getContext()).inflate(mLayout, viewGroup, false); 
     } 

     T model = getItem(position); 
     Log.d(TAG, "view obtained"); 
     // Call out to subclass to marshall this model into the provided view 
     populateView(view, model, position); 
     return view; 
    } 

    /** 
    * Each time the data at the given Firebase location changes, this method will be called for 
    * each item that needs to be displayed. The first two arguments correspond to the mLayout and 
    * mModelClass given to the constructor of this class. The third argument is the item's position 
    * in the list. 
    * <p> 
    * Your implementation should populate the view using the data contained in the model. 
    * 
    * @param v  The view to populate 
    * @param model The object containing the data used to populate the view 
    * @param position The position in the list of the view being populated 
    */ 
    protected abstract void populateView(View v, T model, int position); 
} 

FirebaseListAdapter.java

getViewメソッド()と呼ばれることはありません。 logcatで確認できます。ボタンやedittext

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_main" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.hqs.tart.fragments.ChatFragment" > 

<android.support.design.widget.FloatingActionButton 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:clickable="true" 
    android:id="@+id/fab" 
    android:tint="@android:color/white" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentEnd="true" 
    app:fabSize="mini" /> 

<android.support.design.widget.TextInputLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_toLeftOf="@id/fab" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentStart="true"> 

    <EditText 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:hint="Input" 
     android:id="@+id/input_box" 
     /> 
</android.support.design.widget.TextInputLayout> 

<ListView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_alignParentTop="true" 
    android:layout_alignParentStart="true" 
    android:layout_above="@id/fab" 
    android:dividerHeight="16dp" 
    android:divider="@android:color/transparent" 
    android:id="@+id/list_of_messages" 
    android:layout_marginBottom="16dp"/> 
</RelativeLayout> 

fragment_chat_list.xml リストのレイアウト。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" android:layout_height="match_parent"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentStart="true" 
     android:id="@+id/message_user" 
     android:textStyle="normal|bold" /> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignBottom="@+id/message_user" 
     android:layout_alignParentEnd="true" 
     android:id="@+id/message_time" /> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/message_user" 
     android:layout_alignParentStart="true" 
     android:layout_marginTop="5dp" 
     android:id="@+id/message_text" 
     android:textAppearance="@style/TextAppearance.AppCompat.Body1" 
     android:textSize="18sp" /> 
</RelativeLayout> 

fragment_chat.xml メッセージのレイアウトファイル

私は、アダプタを右または何かを設定していないよという確信が、私は方法がわかりません。 XMLでもどちらかとは分かりません。

compileSDK 25 
minSDK 19 

私はこの問題を助長する可能性のある断片にも新しくなりました。

EDIT:メインアクティビティは、ナビゲーションドロワーでフラグメントを開きます。それが助けになるか分からない。

+0

これまでは、getCount()が0を返し、Firebaseが正しく設定されていないと判断しました。この特定の設定が機能するかどうかについては、私はまだ分かりません。 – Robokitty

答えて

0

最終的に私たちのAPIは実際にはデータベースから何も受け取っていませんでした。したがって、この問題。 Android Studio経由でFirebaseに接続し、鍵を紛失していると教えてくれました。

関連する問題