Java如何在侦听器外返回变量

时间:2016-08-06 08:10:49

标签: java android

我从下面列出的MainActivity类调用Recipe类的方法getRecipesFromDB。 getRecipesFromDB从Firebase DB检索数据并填充recipeList。我在EventListener的范围内使用时能够成功打印内容。但是当recipeList返回到主类时,它返回null。

问题:我们如何将recipeList返回给MainActivity类?目前它返回null。

代码如下:

 public class Recipe {

  public String title;
  public String description;
  public String image;
  public String url;
  public String dietLabel;

  public Recipe () {
  }

  public String getTitle() {
    return title;
  }
 public String getDescription() {
    return description;
  }
 public String getImageUrl() {
    return image;
  }
 public String getInstructionUrl() {
    return url;
  }
 public String getLabel() { 
    return dietLabel; 
  }

public static ArrayList<Recipe> getRecipesFromDB(){
   final ArrayList<Recipe> recipeList = new ArrayList<>();
   final DatabaseReference mDatabase;
   final Recipe recipe = new Recipe();


mDatabase = FirebaseDatabase.getInstance().getReference("recipes");

mDatabase.addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    System.out.println("There are " + snapshot.getChildrenCount() + " recipes");

    for (DataSnapshot postSnapshot : snapshot.getChildren()) {
      Recipe post = postSnapshot.getValue(Recipe.class);

      recipe.title = post.getTitle();
      recipe.description = post.getDescription();
      recipe.image = post.getImageUrl();
      recipe.url = post.getInstructionUrl();
      recipe.dietLabel = post.getLabel();

      recipeList.add(recipe);
    }
 }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    System.out.println("The read failed: " + databaseError.getMessage());
  }
});

return recipeList; //This return null
/*I am trying to return as above to another class where it is called but this returns null. What needs to be done for this to return the recipeList which has been set inside the listener?*/
  }
}

/* Below is the class where the Recipe.getRecipesFromDB is called */

public class MainActivity extends AppCompatActivity {
  private ListView mListView;

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

  mListView = (ListView) findViewById(R.id.recipe_list_view);

  final ArrayList<Recipe> recipeList = Recipe.getRecipesFromDB();

  RecipeAdapter adapter = new RecipeAdapter(this, recipeList);
  mListView.setAdapter(adapter);
 }
}

1 个答案:

答案 0 :(得分:2)

其中一种方法:您可以将接口从MainActivity传递到侦听器类,然后在收到侦听器时使用侦听器中的数据调用该方法。在MainActivity中实现界面。它可以是:

public interface DataListener {
    void newDataReceived(ArrayList<Recipe> recipeList);
}

修改:用法示例:

您需要将侦听器方法定义为:

public static ArrayList<Recipe> getRecipesFromDB(DataListener dataListener){
   final ArrayList<Recipe> recipeList = new ArrayList<>();
   final DatabaseReference mDatabase;
   final Recipe recipe = new Recipe();


  mDatabase = FirebaseDatabase.getInstance().getReference("recipes");

 mDatabase.addValueEventListener(new ValueEventListener() {
  @Override 
  public void onDataChange(DataSnapshot snapshot) {
    System.out.println("There are " + snapshot.getChildrenCount() + " recipes");

    for (DataSnapshot postSnapshot : snapshot.getChildren()) {
      Recipe post = postSnapshot.getValue(Recipe.class);

      recipe.title = post.getTitle();
      recipe.description = post.getDescription();
      recipe.image = post.getImageUrl();
      recipe.url = post.getInstructionUrl();
      recipe.dietLabel = post.getLabel();

      recipeList.add(recipe);
    } 

    // Transaction complete, sending to listener
    dataListener.newDataReceived(recipeList);
 } 

您需要使用DataListener的实例调用此方法。你可以匿名称呼它:

getRecipesFromDB(new DataListener() {
    @Overrride
    public void newDataReceived(recipeList) {
         // Data will be received here
    }
});

或者,您可以让MainActivity实施该方法:

public class MainActvity implements DataListener {
    ...
    @Overrride
    public void newDataReceived(recipeList) {
         // Data will be received here
    }
    ...
}