我有一个基于Firebase监听器更新的动态ListView。我最初填充ListView,然后当项目添加到Firebase时,我调用notifySetDataChanged()来更新ListView。
代码:
public class Discussion_Activity extends AppCompatActivity {
private ImageView mPollImage;
private TextView mPollCommentQuestion;
private EditText mUserComment;
private String mUserID;
private ImageView mUserAvatar;
private ListView mPollCommentsList;
private ArrayAdapter<Comments> mCommentAdapter;
private int mNumberOfCommentsAtPoll;
private ArrayList<Comments> mCommentArrayList;
private ArrayList<String> mCommentIDArrayList;
private Firebase mBaseRef;
private Firebase mPollsRef;
private Firebase mUpdateRef;
private Firebase mCommentsRef;
private DateFormat mDateFormat;
private Date mDate;
private String mCurrentDateString;
private int mPollIndex;
private ChildEventListener mUpdateComments;
private Toolbar toolbar;
private static final String FIREBASE_URL = "https://fan-polls.firebaseio.com/";
private static final String COMMENTS_LABEL = "Comments";
private static final String POLLS_LABEL = "Polls";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Firebase.setAndroidContext(this);
setContentView(R.layout.activity_discussion);
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
setTitle(R.string.discussion_title_text);
mDateFormat = new SimpleDateFormat("MM-dd-yyyy");
mDate = new Date();
mCurrentDateString = mDateFormat.format(mDate);
mBaseRef = new Firebase(FIREBASE_URL);
mPollsRef = mBaseRef.child(POLLS_LABEL);
mPollImage = (ImageView) findViewById(R.id.comments_image);
mPollCommentQuestion = (TextView) findViewById(R.id.poll_comment_question);
mUserComment = (EditText) findViewById(R.id.user_comment);
mUserAvatar = (ImageView) findViewById(R.id.profile_image_avatar);
mPollCommentsList = (ListView) findViewById(R.id.poll_comments_list);
mCommentArrayList = new ArrayList<Comments>();
mCommentIDArrayList = new ArrayList<String>();
mCommentAdapter = new ListAdapter(getApplicationContext(), R.layout.individual_comment, mCommentArrayList);
mPollCommentsList.setAdapter(mCommentAdapter);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Intent intent = getIntent();
String pollID = intent.getStringExtra("POLL_ID");
mPollIndex = intent.getIntExtra("POLL_INDEX", 0);
mUpdateRef = mPollsRef.child(mCurrentDateString).child(String.valueOf(mPollIndex + 1));
mCommentsRef = mUpdateRef.child(COMMENTS_LABEL);
mUpdateRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
setImage(dataSnapshot);
setQuestion(dataSnapshot);
createInitialCommentArray(dataSnapshot);
mNumberOfCommentsAtPoll = (int) dataSnapshot.child(COMMENTS_LABEL).getChildrenCount();
for (int i = 0; i < mNumberOfCommentsAtPoll; i++){
String commentID = (String) dataSnapshot.child(COMMENTS_LABEL).child(mCommentIDArrayList.get(i)).child("COMMENT").getValue();
Log.v("COMMENT_ID", "The comment ID is " + commentID);
String userID = (String) dataSnapshot.child(COMMENTS_LABEL).child(mCommentIDArrayList.get(i)).child("USER_ID").getValue();
Log.v("USER_ID", "The user ID is " + userID);
mCommentArrayList.add(new Comments(mUserAvatar, userID, commentID));
mCommentAdapter.notifyDataSetChanged();
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
//TODO: Store unique comment ID's in an array
//TODO: Figure out how to programmatically add images to AWS and then store URL in Firebase
ImageView fab = (ImageView) findViewById(R.id.add_comment);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
HashMap<String, Object> commentMap = new HashMap<String, Object>();
commentMap.put("USER_ID", mBaseRef.getAuth().getUid());
commentMap.put("COMMENT", mUserComment.getText().toString());
mUpdateRef.child(COMMENTS_LABEL).push().updateChildren(commentMap);
mCommentAdapter.notifyDataSetChanged();
hideKeyboard(view);
mUserComment.setText("");
Toast.makeText(getApplicationContext(),R.string.comment_added, Toast.LENGTH_LONG).show();
}
});
}
//How to iterate through a Firbease database
private void createInitialCommentArray(DataSnapshot dataSnapshot) {
for (DataSnapshot s : dataSnapshot.child(COMMENTS_LABEL).getChildren()) {
mCommentIDArrayList.add(s.getKey());
Log.v("COMMENT_ARRAY", "The comment array is " + s.getKey());
}
}
@Override
protected void onStart() {
super.onStart();
mUpdateComments = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
mCommentIDArrayList.add(dataSnapshot.getKey());
String commentID = (String) dataSnapshot.child("COMMENT").getValue();
Log.v("New_Comment", "The new comment is " + commentID);
String userID = (String) dataSnapshot.child("USER_ID").getValue();
Log.v("New_User_ID", "The new userID is " + userID);
mCommentArrayList.add(new Comments(mUserAvatar, userID, commentID));
mCommentAdapter.notifyDataSetChanged();
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
};
//TODO: Keep listeners lean; only add listener to the specific root of the data
mCommentsRef.addChildEventListener(mUpdateComments);
}
@Override
protected void onStop() {
super.onStop();
mCommentsRef.removeEventListener(mUpdateComments);
}
private void setQuestion(DataSnapshot dataSnapshot) {
String pollQuestion = (String) dataSnapshot.child("Poll_Question").getValue();
if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
mPollCommentQuestion.setTextSize(24);
} else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {
mPollCommentQuestion.setTextSize(18);
} else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
mPollCommentQuestion.setTextSize(14);
} else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) {
mPollCommentQuestion.setTextSize(14);
}
mPollCommentQuestion.setText(pollQuestion);
}
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
适配器 -
public class ListAdapter extends ArrayAdapter<Comments> {
public ListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
public ListAdapter(Context context, int resource, List<Comments> items) {
super(context, resource, items);
}
@Override
public int getCount() {
return mNumberOfCommentsAtPoll;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.individual_comment, null);
}
Comments p = getItem(position);
if (p != null) {
TextView userID = (TextView) v.findViewById(R.id.user_ID);
TextView userComment = (TextView) v.findViewById(R.id.user_comment);
if (userID != null) {
userID.setText(p.getUserID());
}
if (userComment != null) {
userComment.setText(p.getUserComment());
}
}
return v;
}
}
private void setImage(DataSnapshot dataSnapshot) {
String imageURL = (String) dataSnapshot.child("Image").getValue();
Picasso.with(getApplicationContext())
.load(imageURL)
.transform(new RoundedTransformation(10, 6))
.fit()
.into((mPollImage));
mPollImage.setColorFilter(Color.argb(140, 255, 255, 255)); // White Tint
}
}
答案 0 :(得分:1)
您使用了addListenerForSingleValueEvent()
,它只会被调用一次,并且在被调用后会被取消注册。因此,如果您更改了firebase数据库中的数据(正如您在fab
onclick中所做的那样),那么当您的监听器不再注册时,您将无法获得更改数据的回调。
对于您的任务,您需要使用addValueEventListener()
或实现Child事件侦听器。
是的,不要忘记在不再需要它时删除它们。
您的onChildAdded()
存在问题。
String commentID = (String) dataSnapshot.child(COMMENTS_LABEL).child(pollCount).child("COMMENT").getValue();
String userID = (String) dataSnapshot.child(COMMENTS_LABEL).child(pollCount).child("USER_ID").getValue();
以上陈述的行为不会像您期望的那样。
根据您的工厂fab.setOnClickListener()
,您将生成随机唯一键作为COMMENTS_LABEL的子项,并且该键包含您的user_id和注释。
但是你试图使用索引0,1,2等从COMMENTS_LABEL的子节点获取user_id和注释。这将永远不会获取您保存的确切值,因为您不知道什么是唯一ID。
你需要像这样改变onChildAdded()
-
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String commentID = (String) dataSnapshot.child(COMMENTS_LABEL).child(dataSnapshot.getKey()).child("COMMENT").getValue();
String userID = (String) dataSnapshot.child(COMMENTS_LABEL).child(dataSnapshot.getKey()).child("USER_ID").getValue();
mCommentArrayList.add(new Comments(mUserAvatar, userID, commentID));
mCommentAdapter.notifyDataSetChanged();
}