Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 一旦数据在recyclerview适配器上更新,如何将字体从粗体改为普通?_Android_Firebase_Firebase Realtime Database_Android Recyclerview_Android Adapter - Fatal编程技术网

Android 一旦数据在recyclerview适配器上更新,如何将字体从粗体改为普通?

Android 一旦数据在recyclerview适配器上更新,如何将字体从粗体改为普通?,android,firebase,firebase-realtime-database,android-recyclerview,android-adapter,Android,Firebase,Firebase Realtime Database,Android Recyclerview,Android Adapter,我正在使用Firebase数据和RecyclerViewAdapter 该场景是当用户单击列表时,初始状态为未读将更改为已读,因此字体应从粗体更改为普通 我当前将状态从未读更改为已读的后端流程正在运行并更新到Firebase,但是我的特定回收视图项的界面没有从粗体更改为正常 我的想法是,无需回调Firebase数据即可读取状态,但界面应根据用户单击进行更改 有人能帮我吗? NotificationActivity.java: package com.myapp.activity.notific

我正在使用Firebase数据和
RecyclerView
Adapter

该场景是当用户单击列表时,初始状态为
未读
将更改为
已读
,因此
字体
应从
粗体
更改为
普通

我当前将状态从
未读
更改为
已读
的后端流程正在运行并更新到Firebase,但是我的特定
回收视图
项的界面没有从
粗体
更改为
正常

我的想法是,无需回调Firebase数据即可读取状态,但界面应根据用户单击进行更改

有人能帮我吗?


NotificationActivity.java

package com.myapp.activity.notification;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.material.nereeducation.R;
import com.material.nereeducation.adapter.AdapterNotification;
import com.material.nereeducation.model.Notification;
import com.material.nereeducation.utils.Tools;
import com.material.nereeducation.widget.LineItemDecoration;

import java.util.ArrayList;
import java.util.List;

public class NotificationActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private AdapterNotification mAdapter;
    private ActionModeCallback actionModeCallback;
    private ActionMode actionMode;
    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification);

        initToolbar();
        initComponent();
        Tools.setSystemBarColor(this, R.color.black);
    }

    private void initToolbar() {
        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle("Notifications");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    private List<Notification> items = new ArrayList<>();
    private LinearLayout messageEmptyList;
    private void initComponent() {

        messageEmptyList = findViewById(R.id.messageEmptyList);
        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.addItemDecoration(new LineItemDecoration(this, LinearLayout.VERTICAL));
        recyclerView.setHasFixedSize(true);

        //set data and list adapter
        mAdapter = new AdapterNotification(this, items);
        recyclerView.setAdapter(mAdapter);
        mAdapter.setOnClickListener(new AdapterNotification.OnClickListener() {

            @Override
            public void onItemClick(View view, Notification obj, int pos) {
                if (mAdapter.getSelectedItemCount() > 0) {
                    enableActionMode(pos);
                } else {
                    // read the inbox which removes bold from the row
                    Notification notification = mAdapter.getItem(pos);
                    Toast.makeText(getApplicationContext(), "Read: " + notification.sender_id, Toast.LENGTH_SHORT).show();

                    updateStatus(notification.notificationId,"read",pos);

                }
            }

            @Override
            public void onItemLongClick(View view, Notification obj, int pos) {
                enableActionMode(pos);
            }
        });

        actionModeCallback = new ActionModeCallback();

        getNotificationData();

    }

    private void getNotificationData()
    {
        items.clear();
        GsonBuilder builder = new GsonBuilder();
        final Gson gson = builder.create();

        FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
        String uuid = firebaseAuth.getUid();

        FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
        DatabaseReference databaseReference = firebaseDatabase.getReference();

        databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                if(dataSnapshot.getValue() != null)
                {
                    for(DataSnapshot snapshot: dataSnapshot.getChildren())
                    {
                        String dataReceived = gson.toJson(snapshot.getValue());
                        Notification notificationItems = gson.fromJson(dataReceived, Notification.class);
                        items.add(notificationItems);
                    }
                    mAdapter.notifyDataSetChanged();
                }else
                {
                    messageEmptyList.setVisibility(View.VISIBLE);
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }

    private void updateStatus(final String notificationId, String status, final int position) {
        FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
        String uuid = firebaseAuth.getUid();

        FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
        DatabaseReference databaseReference = firebaseDatabase.getReference();

        databaseReference.child("notifications/"+uuid+"/data_notification").child(notificationId).child("status").setValue(status
        ).addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                mAdapter.notifyItemChanged(position); //Problem here - how to update text from BOLD to NORMAL for this item?
            }
        });
    }

    private void enableActionMode(int position) {
        if (actionMode == null) {
            actionMode = startSupportActionMode(actionModeCallback);
        }
        toggleSelection(position);
    }

    private void toggleSelection(int position) {
        mAdapter.toggleSelection(position);
        int count = mAdapter.getSelectedItemCount();

        if (count == 0) {
            actionMode.finish();
        } else {
            actionMode.setTitle(String.valueOf(count));
            actionMode.invalidate();
        }
    }

    private class ActionModeCallback implements ActionMode.Callback {
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            mode.getMenuInflater().inflate(R.menu.menu_delete, menu);
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            int id = item.getItemId();
            if (id == R.id.action_delete) {
                deleteInboxes();
                mode.finish();
                return true;
            }
            return false;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mAdapter.clearSelections();
            actionMode = null;
        }
    }

    private void deleteInboxes() {
        List<Integer> selectedItemPositions = mAdapter.getSelectedItems();
        for (int i = selectedItemPositions.size() - 1; i >= 0; i--) {
            mAdapter.removeData(selectedItemPositions.get(i));
        }
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
        } else {
            Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
        }
        return super.onOptionsItemSelected(item);
    }
}
package com.myapp.adapter;

import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.support.v7.widget.RecyclerView;
import android.text.format.DateUtils;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.material.nereeducation.R;
import com.material.nereeducation.helper.AlphabetColor;
import com.material.nereeducation.model.Notification;
import com.material.nereeducation.utils.Tools;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class AdapterNotification extends RecyclerView.Adapter<AdapterNotification.ViewHolder> {

    private Context ctx;
    private List<Notification> items;
    private OnClickListener onClickListener = null;

    private SparseBooleanArray selected_items;
    private int current_selected_idx = -1;

    private AlphabetColor alphabetColor;

    public void setOnClickListener(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }


    public class ViewHolder extends RecyclerView.ViewHolder {

        public TextView from, title, message, date, image_letter;
        public ImageView image;
        public RelativeLayout lyt_checked, lyt_image;
        public View lyt_parent;

        public ViewHolder(View view) {
            super(view);
            from = view.findViewById(R.id.from);
            title = view.findViewById(R.id.title);
            message = view.findViewById(R.id.message);
            date = view.findViewById(R.id.date);
            image_letter = view.findViewById(R.id.image_letter);
            image = view.findViewById(R.id.image);
            lyt_checked = view.findViewById(R.id.lyt_checked);
            lyt_image = view.findViewById(R.id.lyt_image);
            lyt_parent = view.findViewById(R.id.lyt_parent);
        }
    }

    public AdapterNotification(Context mContext, List<Notification> items) {
        this.ctx = mContext;
        this.items = items;
        selected_items = new SparseBooleanArray();
        alphabetColor = new AlphabetColor(mContext);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_notification, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        final Notification notification = items.get(position);

        // displaying text view data

        System.out.println("sender type:"+notification.sender_type);
        Character firstLetter;
        if(notification.sender_type.equals("1")) //Admin
        {
            String admin = ctx.getString(R.string.admin_name);
            holder.from.setText(admin);
            firstLetter = admin.substring(0, 1).charAt(0);

            holder.image_letter.setText(String.valueOf(firstLetter));
        }else
        {
            holder.from.setText(notification.senderName);
            firstLetter = notification.senderName.substring(0, 1).charAt(0);
            holder.image_letter.setText(String.valueOf(firstLetter));
        }
        if(notification.status.equals("unread"))
        {
            holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
            holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
        }

        holder.title.setText(notification.title);
        holder.message.setText(notification.message);
        holder.date.setText(getDate(Long.parseLong(notification.date)));

        holder.lyt_parent.setActivated(selected_items.get(position, false));

        holder.lyt_parent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onClickListener == null) return;
                onClickListener.onItemClick(v, notification, position);
            }
        });

        holder.lyt_parent.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (onClickListener == null) return false;
                onClickListener.onItemLongClick(v, notification, position);
                return true;
            }
        });

        toggleCheckedIcon(holder, position);
        displayImage(holder, notification, firstLetter);

    }

    private void displayImage(ViewHolder holder, Notification notification, Character firstLetter) {
        if (notification.image != null) {
            Tools.displayImageRound(ctx, holder.image, notification.image);
            holder.image.setColorFilter(null);
            holder.image_letter.setVisibility(View.GONE);
        } else {
            holder.image.setImageResource(R.drawable.shape_circle);
            holder.image.setColorFilter(alphabetColor.getColorByAlphabet(firstLetter), PorterDuff.Mode.MULTIPLY);
            holder.image_letter.setVisibility(View.VISIBLE);
        }
    }

    private String getDate(long time) {
        Date date = new Date();
        long currentTime = date.getTime();
        String result = (String) DateUtils.getRelativeTimeSpanString(time, currentTime, 0);
        return result;
    }



    private void toggleCheckedIcon(ViewHolder holder, int position) {
        if (selected_items.get(position, false)) {
            holder.lyt_image.setVisibility(View.GONE);
            holder.lyt_checked.setVisibility(View.VISIBLE);
            if (current_selected_idx == position) resetCurrentIndex();
        } else {
            holder.lyt_checked.setVisibility(View.GONE);
            holder.lyt_image.setVisibility(View.VISIBLE);
            if (current_selected_idx == position) resetCurrentIndex();
        }
    }

    public Notification getItem(int position) {
        return items.get(position);
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    public void toggleSelection(int pos) {
        current_selected_idx = pos;
        if (selected_items.get(pos, false)) {
            selected_items.delete(pos);
        } else {
            selected_items.put(pos, true);
        }
        notifyItemChanged(pos);
    }

    public void clearSelections() {
        selected_items.clear();
        notifyDataSetChanged();
    }

    public int getSelectedItemCount() {
        return selected_items.size();
    }

    public List<Integer> getSelectedItems() {
        List<Integer> items = new ArrayList<>(selected_items.size());
        for (int i = 0; i < selected_items.size(); i++) {
            items.add(selected_items.keyAt(i));
        }
        return items;
    }

    public void removeData(int position) {
        items.remove(position);
        resetCurrentIndex();


    }

    private void resetCurrentIndex() {
        current_selected_idx = -1;
    }

    public interface OnClickListener {
        void onItemClick(View view, Notification obj, int pos);

        void onItemLongClick(View view, Notification obj, int pos);
    }
}

对于这种情况,您还需要处理其他问题

if(notification.status.equals("unread")){
   holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
   holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
}else{
   holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
   holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
}

如果您想在适配器中设置textview不同的字体或颜色,您需要检查每个位置,因此在您的情况下,您只需为textview设置粗体字体,就必须为默认textview字体重新设置普通字体

在adapter中将字体设置为正常

为textview设置文本默认字体,如下所示

holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
   holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
然后检查项目状态是否为未读

   if(notification.status.equals("unread")){
       holder.from.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
       holder.title.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
    }

因此,我想您的问题是,状态(已读/未读)应用于数据库,但没有反映在recycler视图上

如果这是问题所在,主要是因为您没有处理列表的数据更改方法(并使用新值更新它)

您当前正在使用此选项获取数据:

       databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {.....
这不会帮助您控制更改的项目

可能的解决方案

解决此问题的一种方法是使用(FirebaseUI)数据库而不是自定义适配器

FirebaseUI将侦听更改并更新列表

编辑2

对单值事件使用ChildEventListener而不是Listener

与此相反:

     databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {.....
使用以下命令:

     databaseReference.child("notifications/"+uuid+"/data_notification").orderByChild("status").startAt("read").endAt("unread").addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot) {.....


        //add items to list (like you did)



         @Override
        public void onChildChanged(DataSnapshot dataSnapshot) {.....

        //set the items again to the list (update them here) and notify
        //data set changed (so values update in your list).

我相信你应该这样设置字体:

if ("unread".equals(notification.status)) {
    holder.from.setTypeface(null, Typeface.BOLD);
    holder.title.setTypeface(null, Typeface.BOLD);
} else {
    holder.from.setTypeface(null, Typeface.NORMAL);
    holder.title.setTypeface(null, Typeface.NORMAL);
}

该视图正被
RecyclerView
重新使用,因此,一旦将字体设置为粗体,您需要在下次使用该视图时将其设置回正常状态。

为什么要向下投票?有什么原因吗?结果还是一样。。。我的意思是,在数据更改后,粗体仍然没有更改为Normal您确定已经将新值更新到适配器吗?mAdapter.notifyItemChanged(位置);似乎您刚刚告诉适配器使用旧数据刷新。您需要先更新该行的notification.status,然后调用mAdapter.notifyItemChanged(position)无更改,我的意思是在数据更改后,粗体仍不能更改为正常。。。如何仅直接更改该项而不是使用
item.clear()
?item.clear()的需要是什么;您可以使用刚刚设置的适配器引用单个位置。notifyItemChanged(int-position)我尝试过,但该项目没有刷新。但风格还是一样。我认为称为的旧数据没有更新。如何在调用方法
updateStatus()
后才能像
text.setText(“新数据”)
那样设置该项?我认为您的数据正在刷新,但问题是您没有更新arraylist位置,您还必须更新特定职位以反映数据。是否打印notification的值。在参考数据后,该特定职位的状态您将了解实际问题出在何处如何使用FirebaseUI?我们能不能只关注recyclerview?