首页 > 解决方案 > 如何使用 RecyclerView 从 Firebase 获取密钥

问题描述

这是一个使用 Firebase-UI:3.3.0 和 RecyclerView com.android.support:recyclerview-v7:27.1.1 的待办事项列表应用程序。我可以将数据发送到 Firebase 实时数据库。但我无法从我的数据库中检索密钥。因此,我无法显示包含列表项的详细信息视图。

应用级 gradle 文件:

apply plugin: 'com.android.application

android {
    compileSdkVersion 27
    defaultConfig {
    applicationId "com.example.nikhil.todolist"
    minSdkVersion 15
    targetSdkVersion 27
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
packagingOptions{
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/LICENSE-FIREBASE.txt'
    exclude 'META-INF/NOTICE'

    }
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.android.support:design:27.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
compile 'com.google.firebase:firebase-core:12.0.1'
compile 'com.google.firebase:firebase-database:12.0.1'
compile 'com.firebase:firebase-client-android:2.4.0'
compile 'com.firebaseui:firebase-ui-database:3.3.0'
}

apply plugin: 'com.google.gms.google-services'`

Main.java它包含我的 recyclerView:

package com.example.nikhil.todolist;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
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.widget.TextView;

import com.firebase.client.Firebase;
import com.google.firebase.database.ChildEventListener;
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 java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    public static final String Firebase_Server_URL = "https://todolist-4f4cf.firebaseio.com/";

Firebase firebase;

public static final String Database_Path = "Tasks";
DatabaseReference databaseReference;

List<String> keyArray = new ArrayList<>();

List<Task> list = new ArrayList<>();

RecyclerView recyclerView;

RecyclerViewAdapter adapter ;
public static String keyValue;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    Firebase.setAndroidContext(MainActivity.this);

    //Adding values to banner
    TextView bannerDay = (TextView) findViewById(R.id.bannerDay);
    TextView bannerDate = (TextView) findViewById(R.id.bannerDate);

    SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
    Date d = new Date();
    String dayOfTheWeek = sdf.format(d);
    bannerDay.setText(dayOfTheWeek);

    long date = System.currentTimeMillis();
    SimpleDateFormat sdf1 = new SimpleDateFormat("MMM MM dd,yyy h:mm a");
    String dateString = sdf1.format(date);
    bannerDate.setText(dateString);

    firebase = new Firebase(Firebase_Server_URL);

    recyclerView = (RecyclerView) findViewById(R.id.task_list);

    recyclerView.setHasFixedSize(true);

    recyclerView.setLayoutManager(new LinearLayoutManager(this));

    databaseReference = 
FirebaseDatabase.getInstance().getReference(Database_Path);


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

                Task task = dataSnapshot.getValue(Task.class);

                keyValue = dataSnapshot.getRef().getKey().toString() ;

                keyArray.add(keyValue);

                list.add(task);


            adapter = new RecyclerViewAdapter(MainActivity.this, list);

            recyclerView.setAdapter(adapter);
        }

        @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(DatabaseError databaseError) {

        }
    });

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}


@Override
protected void onStart() {
    super.onStart();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }
    else if(id == R.id.addTask){
        Intent addIntent = new Intent(MainActivity.this,AddTask.class);
        startActivity(addIntent);
    }

    return super.onOptionsItemSelected(item);
}

public String getKeyValue(){
    System.out.println("----------------------------------------------------------------->"+keyArray);
    System.out.println("this is the KeyValue================================="+keyValue);
    return keyValue;
}

RecyclerViewAdapter.java包含 ViewHolder 和 RecyclerView 填充:

package com.example.nikhil.todolist;

import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


import java.util.List;


public class RecyclerViewAdapter extends 
RecyclerView.Adapter<RecyclerViewAdapter.TaskViewHolder> {

Context context;
List <Task> DataList;
MainActivity mActivity= new MainActivity();

public RecyclerViewAdapter(Context context, List<Task> TempList) {

    this.DataList = TempList;

    this.context = context;
}

@NonNull
@Override
public TaskViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.task_row, parent, false);

    return new TaskViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull TaskViewHolder holder, int position) {
    Task task = DataList.get(position);

    final String key_value = mActivity.getKeyValue();

    holder.task_name.setText(task.getName());
    holder.task_time.setText(task.getTime());


    holder.mview.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent singleActivity = new Intent(context,single_task.class);
            singleActivity.putExtra("TaskId",key_value);
            System.out.println("KeyValue is ================================================>"+key_value);
            context.startActivity(singleActivity);
        }
    });
}

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


public static class TaskViewHolder extends RecyclerView.ViewHolder{

    View mview;
    public TextView task_name;
    public TextView task_time;

    public TaskViewHolder(View itemView) {
        super(itemView);
        mview = itemView;
        task_name = itemView.findViewById(R.id.taskName);
        task_time = itemView.findViewById(R.id.taskTime);
    }

    public void setName(String name){
        task_name.setText(name);
    }

    public void setTime(String time){
        task_time.setText(time);
    }
}
}

Task.java是我的 recyclerView 的模型类:

package com.example.nikhil.todolist;

import java.text.SimpleDateFormat;


public class Task {

long date = System.currentTimeMillis();
SimpleDateFormat sdf1 = new SimpleDateFormat("MMM MM dd,yyy h:mm a");
String dateString = sdf1.format(date);

private String Name = "DewBamb";
private String Time = dateString;

public Task(){
}

public Task(String name,String time){

    this.Name = name;
    this.Time = time;
}
public String getTime(){
    return  Time;
}

public String getName(){
    return Name;
}

public void setTime(String time){
    this.Time= time;
}

public void setName(String name){
    this.Name = name;
}
}

AddTask.java我使用这个类向我的 fireBase 数据库添加信息:

package com.example.nikhil.todolist;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

import java.text.SimpleDateFormat;

public class AddTask extends AppCompatActivity {
private FirebaseDatabase database;
private DatabaseReference myRef;
EditText editTask;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_task);
    database = FirebaseDatabase.getInstance();
    editTask= (EditText)findViewById(R.id.editText);
}

public void addButtonClicked(View view) {

    String name = editTask.getText().toString();

    long date = System.currentTimeMillis();

    SimpleDateFormat sdf = new SimpleDateFormat("MMM MM dd, yyyy h:mm a");
    String dateString = sdf.format(date);

    myRef = database.getInstance().getReference().child("Tasks");

    if(editTask.getText().toString().isEmpty()){
        Toast.makeText(this,"Please Add text",Toast.LENGTH_LONG).show();
    }
    else{
        DatabaseReference newTask = myRef.push();
        newTask.child("name").setValue(name);
        newTask.child("time").setValue(dateString);
        editTask.setText("");
        Toast.makeText(AddTask.this, "Message Saved",
                Toast.LENGTH_LONG).show();
    }

}
}

single_Task.java这是我在 recyclerView 中的内容的详细视图,当单击 recyclerView 的特定子项时我想要它:

package com.example.nikhil.todolist;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.TextView;

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 java.util.ArrayList;
import java.util.List;

public class single_task extends AppCompatActivity {

private String task_key = null;
private TextView singleTask, singleTime;
private DatabaseReference mDatabase;

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

    task_key = getIntent().getExtras().getString("TaskId");
    mDatabase = FirebaseDatabase.getInstance().getReference().child("Tasks");

    singleTask = (TextView) findViewById(R.id.Ssingletask);
    singleTime = (TextView) findViewById(R.id.Ssingletime);

    mDatabase.child(task_key).addValueEventListener(new ValueEventListener() 
{
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String task_title = (String) dataSnapshot.child("name").getValue();
            String task_time = (String) dataSnapshot.child("time").getValue();

            singleTask.setText(task_title);
            singleTime.setText(task_time);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}


}

标签: androidfirebasefirebase-realtime-databaseandroid-recyclerview

解决方案


您可以将密钥与您的任务一起保存,如下所示:

public class Task {

    // save your key here in ChildEventListener#onChildAdded()
    // transient because it will be excluded in serializing 
    // and won't save in your database, remove it if you are ok to save it.
    private transient String key;

    //... other code skipped.

    public Task() {
    }

    //... other code skipped.

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

    public String getKey() {
        return key;
    }

    //... other code skipped.
}

然后代替keyArray.add(keyValue);执行以下操作:

@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
    Task task = dataSnapshot.getValue(Task.class);

         // as per Franks comment.
    keyValue = dataSnapshot.getKey();

    task.setKey(keyValue);

    //... other code skipped.
}

然后RecyclerViewAdapter你可以key像这样引用:

@Override
public void onBindViewHolder(@NonNull TaskViewHolder holder, int position) {
    Task task = DataList.get(position);

    holder.task_name.setText(task.getName());
    holder.task_time.setText(task.getTime());


    holder.mview.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent singleActivity = new Intent(context, single_task.class);
            singleActivity.putExtra("TaskId", task.getKey());
            System.out.println("KeyValue is ================================================>" + task.getKey());
            context.startActivity(singleActivity);
        }
    });
}

建议:如果您制作您的Task对象Parcelable,或者Serializable您可以SingleActivity直接将任务发送给您,而无需再次从远程数据库查询。


推荐阅读