简体   繁体   English

如何从 Firebase 检索数据到 ListView(使用自定义数组适配器)

[英]How to retrieve data from Firebase into a ListView (with custom Array Adapter)

I have currently designed a place explorer app with 3 items displayed in a list view.我目前设计了一个地点浏览器应用程序,其中 3 个项目显示在列表视图中。 When a user logs in he will find a list of categories.当用户登录时,他会找到一个类别列表。 On clicking a category the list of places under that category will appear.单击一个类别时,将显示该类别下的地点列表。 I have linked the app with Firebase.我已将该应用程序与 Firebase 相关联。

Now, I want to display 2 items ( placeTitle and placeDesc ) from the data stored in the firebase into the list view.现在,我想将 firebase 中存储的数据中的 2 个项目( placeTitleplaceDesc )显示到列表视图中。 I am unable to load the data into the ListView .我无法将数据加载到ListView中。

应用快照

Firebase 快照

Shopping Activity:购物活动:

public class ShoppingActivity extends AppCompatActivity {

    DatabaseReference databaseReference;
    Place shopping;
    ListView listView;
    ArrayList<Place> list;
    ArrayAdapter <Place> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.place_list);
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

        //For accessing firebase data and load into Listview
        list = new ArrayList<>();
        shopping = new Place();
        listView = findViewById(R.id.listView); //listview
        adapter = new ArrayAdapter<>(this, R.layout.custom_list_item, list);
        final PlaceAdapter placeAdapter = new PlaceAdapter(this, list, R.color.category_shopping);
        databaseReference = FirebaseDatabase.getInstance().getReference("PlaceDetails"); //database reference
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                for(DataSnapshot ds: snapshot.getChildren()){

                    Place shopping = ds.getValue(Place.class);

                    if (shopping != null) {

                        list.add(new Place(shopping.getPlaceTitle(),shopping.getPlaceTitle()));
                    }
                }


                listView.setAdapter(placeAdapter);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });


        //Create a new array list of Places
//        final ArrayList<Place> shopping = new ArrayList<>();


//        Place p = new Place("State Museum","Ambari Guwahati");
//        culture.add(p);

        //create a new object for Place and add all place details
//        shopping.add(new Place("Fancy Bazar Daily Market", "Fancy Bazar Guwahati"));
//        shopping.add(new Place("Pentaloons", "Sixmile Guwahati"));
//        shopping.add(new Place("Guwahati Central", "Zoo Road Guwahati"));
//        shopping.add(new Place("Eastrends (Hub)", "Bhangagarh Guwahati"));
//        shopping.add(new Place("City Centre", "G.S. Road Guwahati"));
//        shopping.add(new Place("Central Mall", "G.S. Road Guwahati"));



//        ArrayAdapter<Place> itemsAdapter = new ArrayAdapter<Place>(this, R.layout.custom_list_item, shopping);
//
//        PlaceAdapter placeAdapter = new PlaceAdapter(this, shopping, R.color.category_shopping);
//
//        ListView listView = findViewById(R.id.listView);
//
//        listView.setAdapter(placeAdapter);


        //Displaying the listview items
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //Toast.makeText(CultureActivity.this, "ListView Item is clicked", Toast.LENGTH_SHORT).show();

                //For opening a new view in google maps
                // Get the {@link Word} object at the given position the user clicked on
                Place place = list.get(position);

                // Create a Uri from an intent string. Use the result to create an Intent to open the place in Google Maps
                Uri gmmIntentUri = Uri.parse("geo:0,0?q=" + Uri.encode(place.getPlaceTitle()));


                //Uri gmmIntentUri = Uri.parse("geo:0,0?place");

                //The below Intent will request turn-by-turn navigation to the Place clicked
                //Uri gmmIntentUri = Uri.parse("google.navigation:q="+Uri.encode(place.getPlaceTitle()));

                // Create an Intent from gmmIntentUri. Set the action to ACTION_VIEW
                Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
                // Make the Intent explicit by setting the Google Maps package
                mapIntent.setPackage("com.google.android.apps.maps");

                // Attempt to start an activity that can handle the Intent
                if (mapIntent.resolveActivity(getPackageManager()) != null) {
                    startActivity(mapIntent);

                }
            }
        });
    }
}

Place object放置 object

package android.example.com.knowguwahaticity;

import android.content.Context;

public class Place {


    //Declare the state of the Place class
    //Place Title
    private String mPlaceTitle;

    //Place Desc
    private String mPlaceDesc;

    // Drawable resource ID
    private int mImageResourceId = NO_IMAGE_PROVIDED;

    //Drawable resource ID
    private int mPlaceResourceId;

    //Image visibility
    private static final int NO_IMAGE_PROVIDED = -1 ;


    //Construct the custom class Place


    public Place() {
    }

    public Place(String placeTitle, String placeDesc, int imageResourceId) {
        mPlaceTitle = placeTitle;
        mPlaceDesc = placeDesc;
        mImageResourceId = imageResourceId;
    }

    public Place(String placeTitle, String placeDesc) {
        mPlaceTitle = placeTitle;
        mPlaceDesc = placeDesc;
    }

    //declare the methods to access the states of the class
    //get the Title of the place
    public String getPlaceTitle() {
        return mPlaceTitle;
    }

    //get the Address of the place
    public String getPlaceDesc() {
        return mPlaceDesc;
    }

    //get the image resource id of the image
    public int getImageResourceId() {
        return mImageResourceId;
    }

//    //get the map resource id of the image
//    public int getPlaceResourceId() {
//        return mPlaceResourceId;
//    }

    //check whether the object has an image
    public boolean hasImage(){
        return mImageResourceId != NO_IMAGE_PROVIDED;
    }
}

Custom List view XML自定义列表视图 XML

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:minHeight="@dimen/list_item_height"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/place_image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:src="@drawable/star"
        />

    <LinearLayout

        android:id="@+id/text_container"
        android:layout_width="0dp"
        android:layout_height="@dimen/list_item_height"
        android:layout_weight="1"
        android:orientation="vertical"
        android:paddingLeft="16dp">

        <TextView
            android:id="@+id/title_text_view"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
            android:textColor="@android:color/white"
            android:gravity="bottom"
            android:textSize="18sp"
            android:textStyle="bold"
            tools:text="Title" />

        <TextView
            android:id="@+id/desc_text_view"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
            android:textColor="@android:color/white"
            android:gravity="top|bottom"
            android:textSize="14sp"
            tools:text="Description" />

    </LinearLayout>
</LinearLayout>

PlaceAdapter.java PlaceAdapter.java

package android.example.com.knowguwahaticity;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import java.util.ArrayList;
import java.util.Set;

public class PlaceAdapter extends ArrayAdapter<Place> {

    /** Resource ID for the background color for this list of words */
    private int mColorResourceId;
    private Context mContext;

    public PlaceAdapter(Activity context, ArrayList<Place> places, int colorResourceId) {
        super(context, 0, places);
        mColorResourceId = colorResourceId;

    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        View listItemView = convertView;

        if(listItemView == null) {
            listItemView = LayoutInflater.from(getContext()).inflate(
                    R.layout.custom_list_item, parent, false);
        }

        //get the position of the object at this position of the list
        Place currentPlace = getItem(position);

        //Find the textview in the custom_list_item.xml with id textView1 (Title of the Place)
        TextView TitleTextView = listItemView.findViewById(R.id.title_text_view);
        TitleTextView.setText(currentPlace.getPlaceTitle());


        //Find the textview in the custom_list_item.xml with id textView2 (Desc of the place)
        TextView DescTextView = listItemView.findViewById(R.id.desc_text_view);
        DescTextView.setText(currentPlace.getPlaceDesc());

        // Find the ImageView in the list_item.xml layout with the ID list_item_icon
        ImageView iconView = (ImageView) listItemView.findViewById(R.id.place_image_view);
        // Get the image resource ID from the current Place object and
        // set the image to iconView
        if(currentPlace.hasImage()) {

            iconView.setImageResource(currentPlace.getImageResourceId());

            //set image view as visible
            iconView.setVisibility(View.VISIBLE);
        }
        else {
            //set image view as GONE
            iconView.setVisibility(View.GONE);
        }

        // Find the ImageView in the list_item.xml layout with the ID list_item_icon
//        ImageView mapView = (ImageView) listItemView.findViewById(R.id.place_map_view);
//        // Get the image resource ID from the current Place object and
//        // set the image to iconView
//        mapView.setImageResource(currentPlace.getPlaceResourceId());

        /*Set OnClickListener on the mapView to open the location in map app*/
//        mapView.setTag(position);
//        mapView.setOnClickListener(new View.OnClickListener() {
//
//            @Override
//            public void onClick(View view) {
//                Toast.makeText(mContext, "ImageView clicked for the row = "+view.getTag().toString(), Toast.LENGTH_SHORT).show();
//            }
//        });

        // Set the theme color for the list item
        View textContainer = listItemView.findViewById(R.id.text_container);
        // Find the color that the resource ID maps to
        int color = ContextCompat.getColor(getContext(), mColorResourceId);
        // Set the background color of the text container View
        textContainer.setBackgroundColor(color);


        return listItemView;
    }
}

You are getting a "blank screen" because the name of the properties in your class do not match the name of the properties in the database.您收到“空白屏幕”,因为 class 中的属性名称与数据库中的属性名称匹配。 See, you have a field named mPlaceTitle in your Place class, while in the database is called placeTitle and this is not correct.看,您的Place class 中有一个名为mPlaceTitle的字段,而在数据库中名为placeTitle ,这是正确的。 To solve this, you can simply change the name of all properties in your class to match the one in the database, which are named correct according to the Java Naming Conventions regarding variables.为了解决这个问题,您可以简单地更改 class 中所有属性的名称以匹配数据库中的名称,根据Java 关于变量的命名约定,这些属性的名称是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM