我最近开始学习Android版Firebase。我已经完成了Udacity Firebase Weekend课程,在那里我使用数据库和存储创建了聊天。但是我想了解更多信息,并尝试使其更具交互性,目前,我正努力解决一些技术上很简单的问题,并且希望获得有关操作方法的提示和反馈。
我有一个类CityList
,在其中显示所有使用ListView添加到数据库中的城市。我还有一个浮动按钮,单击后会打开一个EditCity
活动,我可以在该活动中提交另一个城市及其描述(加上照片,但还没有解决)。它工作正常,并且新城市会立即显示在CityList
中。但是,我想做的是单击一个城市名称,然后打开另一个活动,并显示特定的项目,该活动将显示名称+说明+照片。为此,我创建了另一个活动SingleCase
。
我一直在阅读所有有关它的信息,我知道这里有很多答案,但是我觉得我都尝试了所有答案,并且a)它不起作用,通常是因为代码是较旧的版本并且不再支持,b)我不太了解。
CityList.java
public class CityList extends AppCompatActivity {
FirebaseDatabase mFirebaseDatabase;
DatabaseReference mDatabaseReference;
private ListView mListView;
private CityAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cities);
mListView= (ListView) findViewById(R.id.messageListView);
List<City> cities = new ArrayList<>();
mAdapter = new CityAdapter(this, R.layout.item, cities);
mListView.setAdapter(mAdapter);
getData();
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(CityList.this, EditCity.class));
}
});
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String value = (String) parent.getItemAtPosition(position);
startActivity(new Intent(CityList.this, SingleCase.class) .putExtra("value", value));
}
});
}
public void getData() {
mFirebaseDatabase = FirebaseDatabase.getInstance();
mDatabaseReference = mFirebaseDatabase.getReference().child("cities");
mDatabaseReference.addChildEventListener(new ChildEventListener(){
@Override
public void onChildAdded (@NonNull DataSnapshot dataSnapshot, @Nullable String s){
City city = dataSnapshot.getValue(City.class);
key = dataSnapshot.getKey();
mAdapter.add(city);
}
@Override
public void onChildChanged (@NonNull DataSnapshot dataSnapshot, @Nullable String s){
}
@Override
public void onChildRemoved (@NonNull DataSnapshot dataSnapshot){
}
@Override
public void onChildMoved (@NonNull DataSnapshot dataSnapshot, @Nullable String s){
}
@Override
public void onCancelled (@NonNull DatabaseError databaseError){
}
});
}
}
City.java
public class City {
private String title;
private String desc;
public City() {
}
public City(String title, String desc) {
this.title = title;
this.desc = desc;
}
public String getText() {
return title;
}
public void setText(String title) {
this.title = title;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
CityAdapter.java
public class CityAdapter extends ArrayAdapter<City> {
public CityAdapter(Context context, int resource, List<City> objects) {
super(context, resource, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = ((Activity) getContext()).getLayoutInflater().inflate(R.layout.item, parent, false);
}
TextView messageTextView = (TextView) convertView.findViewById(R.id.titleTextView);
TextView descTextView = (TextView) convertView.findViewById(R.id.descTextView);
City city = getItem(position);
messageTextView.setVisibility(View.VISIBLE);
messageTextView.setText(city.getText());
descTextView.setText(city.getDesc());
return convertView;
}
}
SingleCase.java
public class SingleCase extends AppCompatActivity{
FirebaseDatabase mFirebaseDatabase;
DatabaseReference mDatabaseReference;
private ListView mListView;
private CityAdapter mAdapter;
private String position;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.single_case);
position = getIntent().getStringExtra("value");
mListView= (ListView) findViewById(R.id.messageListView);
List<City> cities = new ArrayList<>();
mAdapter = new CityAdapter(this, R.layout.item, cities);
mListView.setAdapter(mAdapter);
getData();
}
public void getData() {
mFirebaseDatabase = FirebaseDatabase.getInstance();
mDatabaseReference = mFirebaseDatabase.getReference().child("cities");
mDatabaseReference.addChildEventListener(new ChildEventListener(){
@Override
public void onChildAdded (@NonNull DataSnapshot dataSnapshot, @Nullable String s){
City city = dataSnapshot.getValue(City.class);
mAdapter.add(city);
}
@Override
public void onChildChanged (@NonNull DataSnapshot dataSnapshot, @Nullable String s){
}
@Override
public void onChildRemoved (@NonNull DataSnapshot dataSnapshot){
}
@Override
public void onChildMoved (@NonNull DataSnapshot dataSnapshot, @Nullable String s){
}
@Override
public void onCancelled (@NonNull DatabaseError databaseError){
}
});
}
}
我经历了无数的教程/视频/论坛,我也在堆栈上阅读了所有类似的问题,但我迷路了。我认为,如果我理解得很好,就应该使用位置,并且我想在CityList
中正确地使用它(和键),但是我不知道接下来在SingleCase
中要实际显示什么它。我正在传递position
值,也可以传递key
,但是我不知道接下来在哪里使用它。我已经读过我也可以使用键,但是同一件事,我尝试在.child("cities").child(key)
中引用SingleCase
,但没有用(应用程序将崩溃)。很抱歉,这是一个简单的问题,还是一个经常被问到的问题,但是我对此并不陌生,我绝对无法掌握position/key
概念以及在这种情况下如何使用它。是的,我也阅读了文档。任何帮助将是巨大的!
如果您需要我发布代码中的其他内容,请告诉我,谢谢。
编辑: 为清楚起见,发布了代码中最关键的部分:
在CityList.java
中,我得到了position
变量(称为value
):
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String value = (String) parent.getItemAtPosition(position);
startActivity(new Intent(CityList.this, SingleCase.class) .putExtra("value", value));
}
});
在这里,我还putExtra
位置(值)并将其“发送”到SingleCase
。我还从这里获得key
中的CityList
:
public void onChildAdded (@NonNull DataSnapshot dataSnapshot, @Nullable String s){
City city = dataSnapshot.getValue(City.class);
key = dataSnapshot.getKey();
mAdapter.add(city);
}
在SingleCase中,我不知道该如何处理这两个参数。我想它们已经正确解析和传输了(密钥还没有传输,但是我可以做到,我只是不确定位置是否不足以使其发挥作用)。
问题是SingleCase.
,我觉得我应该在这里使用键/位置告诉程序我只需要一个特定的City
项,但是我不知道如何。
public void onChildAdded (@NonNull DataSnapshot dataSnapshot, @Nullable String s){
City city = dataSnapshot.getValue(City.class);
mAdapter.add(city);
}