不在Firebase

时间:2017-06-17 18:24:04

标签: android listview firebase

我可以将数据放入Firebase数据库,但是当我想要检索它并将其显示到ListView时,它只显示空白屏幕。

BaseActivity类:

public class BaseActivity extends AppCompatActivity {

    @Bean
    OttoBus bus;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        bus.register(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        bus.unregister(this);
    }
}

HomeActivity类:

@OptionsMenu(R.menu.signout)
@EActivity(R.layout.activity_home)
public class HomeActivity extends BaseActivity {

    private static final int LOGIN_REQUEST_CODE = 42;

    @ViewById
    ListView listView;

    @Bean
    ConversationAdapter conversationAdapter;

    @Bean
    UserDao userDao;

    @AfterViews
    void init() {
        // if no user is logged in
        if (FirebaseAuth.getInstance().getCurrentUser() == null) {
            LoginActivity_.intent(this).startForResult(LOGIN_REQUEST_CODE);
        } else {
            userDao.init();
        }

        listView.setAdapter(conversationAdapter);
    }

    @OnActivityResult(value = LOGIN_REQUEST_CODE)
    void loginSucceeded(int resultCode) {
        if (resultCode != RESULT_OK) {
            return;
        }
        userDao.init();
        conversationAdapter.resetConversationFlow();
    }

    @Subscribe
    public void usersLoaded(UsersLoadedEvent event) {
        final FirebaseUser firebaseUser = FirebaseAuth
                .getInstance().getCurrentUser();
        if (userDao.userExists(firebaseUser.getUid())) {
            userDao.setCurrentUser(userDao.getUserById(firebaseUser.getUid()));
        } else {
            final User user = new User(firebaseUser.getUid(),
                    firebaseUser.getDisplayName(),
                    firebaseUser.getPhotoUrl().toString());
            userDao.write(user);
            userDao.setCurrentUser(user);
        }
    }

    @ItemClick
    void listViewItemClicked(Conversation conversation) {
        ConversationActivity_.intent(this)
                .conversation(conversation)
                .start();
    }

    /**
     * When option item with id signOut is clicked.
     */
    @OptionsItem
    void signOut() {
        FirebaseAuth.getInstance().signOut();

        // restart this activity after user is logged out because if there is no user we will start
        // login activity
        final Intent intent = getIntent();
        finish();
        startActivity(intent);
    }

    /**
     * Called when button with id=fab is clicked.
     */
    @Click
    void fab() {
        CreateConversationActivity_.intent(this).start();
    }
}

activity_home.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.nemus.execomchatworkshop.activity.HomeActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_margin="@dimen/large_margin"
        android:src="@drawable/ic_add_black_24dp" />

</RelativeLayout>

ConversationItemView类:

@EViewGroup(R.layout.item_view_conversation)
public class ConversationItemView extends LinearLayout {

    @ViewById
    TextView title;

    public ConversationItemView(Context context) {
        super(context);
    }

    public void bind(Conversation conversation) {
        title.setText(conversation.getTitle());
    }
}

item_view_conversation.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?android:attr/selectableItemBackground">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/conversationPhoto"
            android:layout_width="@dimen/image_large_size"
            android:layout_height="@dimen/image_large_size"
            android:layout_margin="@dimen/medium_margin" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/large_margin"
            android:orientation="vertical">

            <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:textColor="@color/primary_text"
                android:textSize="@dimen/large_text" />

            <TextView
                android:id="@+id/conversationPreview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:textColor="@color/secondary_text"
                android:textSize="@dimen/medium_text" />

        </LinearLayout>

    </LinearLayout>

</RelativeLayout>

ConversationDao class

@EBean(scope = EBean.Scope.Singleton)
public class ConversationDao {

    static final String CONVERSATION_TAG = "conversations";

    private FirebaseDatabase database = FirebaseDatabase.getInstance();

    private List<Conversation> conversations = new ArrayList<>();

    private Map<String, Conversation> conversationMap = new HashMap<>();

    @Bean
    OttoBus bus;

    /**
     * After this class is injected call this method.
     */
    @AfterInject
    public void init() {
        database.getReference(CONVERSATION_TAG).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                conversationMap = dataSnapshot.getValue(
                        new GenericTypeIndicator<Map<String, Conversation>>() {
                        });
                publish();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }

    public void write(Conversation conversation) {
        final DatabaseReference databaseReference =
                database.getReference(CONVERSATION_TAG).push();

        conversation.setId(databaseReference.getKey());     // set unique key to our conversation
        databaseReference.setValue(conversation);           // push conversation to database
    }

    public List<Conversation> getConversations() {
        return conversations;
    }

    private void publish() {
        conversations.clear();
        if (conversationMap != null) {
            conversations.addAll(conversationMap.values());
        }

        // post to event bus
        bus.post(new ConversationsUpdateEvent());
    }

ConversationAdapter类:

@EBean
public class ConversationAdapter extends BaseAdapter {

    private List<Conversation> conversations = new ArrayList<>();

    @RootContext
    Context context;

    @Bean
    ConversationDao conversationDao;

    @Bean
    OttoBus bus;

    /**
     * This method is called after this class is injected.
     */
    @AfterInject
    void init() {
        bus.register(this);
    }

    public void resetConversationFlow() {
        conversationDao.init();
    }

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

    @Override
    public Conversation getItem(int position) {
        return conversations.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ConversationItemView conversationItemView;

        if (convertView == null) {  // if view item is not created
            conversationItemView = ConversationItemView_.build(context);
        } else {    // if view item was already created
            conversationItemView = (ConversationItemView) convertView;
        }

        // bind data to view
        conversationItemView.bind(getItem(position));

        return conversationItemView;
    }

    private void setConversations(List<Conversation> conversations) {
        this.conversations = conversations;

        // notify that data set changed so that the list is refreshed
        notifyDataSetChanged();
    }

    @Subscribe
    public void conversationsUpdated(ConversationsUpdateEvent event) {
        setConversations(conversationDao.getConversations());
    }
}

那么,我在这里错过了什么。为什么不在ListView中显示会话标题?

1 个答案:

答案 0 :(得分:1)

很难遵循允许一次使用所有这些代码。如果你提出一个小问题而不是一个大问题,你更有可能得到答案。这就是我建议你弄清楚如何解决这个问题:

  1. 熟悉调试器。这是必不可少的,一旦你学会了它,你将会更好地解决任何问题和编码。
  2. 在您成功检索到数据后,设置断点即可停止。然后确认您确实收到了数据,并且它当前存储在您要使用的变量中。

    1. 既然您已确认数据存在,请确保正确设置列表视图。

      首先,我建议你从RecylerView开始,因为这是更新的标准,并且有更多有用的在线教程。它们基本上是一回事,但RecylerView更好。然后我将继续使用调试器来检查我的数据是否正确地传递给RecylerViewAdapter,并且当数据有界时,它会将其指向正确的视图。

    2. Here is a good tutorial for using the Android studio debugger.

      Here is a good tutorial by google for adding lists(Using recylerview)