0

I am creating fragments inside Android Studio where one of my fragments calls an API and displays the listview with a custom listadapter. However, I have read many similar examples but none can determine why my listview is not appearing.

This is my News Fragment:

package com.example.firebasetestapplication;

import android.content.Context;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;

import com.example.firebasetestapplication.databinding.FragmentNewsBinding;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link NewsFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class NewsFragment extends Fragment {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private Handler mHandler = new Handler(Looper.getMainLooper());
    ArrayList<News> newsArrayList = new ArrayList<>();
//    FragmentNewsBinding binding;
//    Context thiscontext;

    public NewsFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment NewsFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static NewsFragment newInstance(String param1, String param2) {
        NewsFragment fragment = new NewsFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_news,container,false);
        TextView textview = v.findViewById(R.id.textview);
        ListView listview = v.findViewById(R.id.listview);

//        thiscontext = container.getContext();
        textview.setText("");

//        textView.setText("Trying for the first time");

//        Inflate the layout for this fragment
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://api.jsonbin.io/v3/b/636b51910e6a79321e444107")
                .get()
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if(response.isSuccessful()) {
                    String myResponse = response.body().string();
                    try {
                        JSONObject jsonObject = new JSONObject(myResponse);
                        JSONObject record = jsonObject.getJSONObject("record");
                        JSONArray club_news = record.getJSONArray("Club_News");
                        Gson gson = new Gson();

                        Type listType = new TypeToken<ArrayList<News>>(){}.getType();
                        List<News> total_News = gson.fromJson(club_news.toString(),listType);

                        for(News news : total_News) {

                            textview.append("Club: " + news.club + " " + news.description + "\n");
                            newsArrayList.add(news);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        ListAdapter listAdapter = new ListAdapter(getActivity(),newsArrayList);
        listview.setAdapter(listAdapter); // line that breaks program

//        mHandler.post(new Runnable() {
//            @Override
//            public void run() {
//                ListAdapter listAdapter = new ListAdapter(getActivity(),newsArrayList);
//                listview.setAdapter(listAdapter); // line that breaks program
//            }
//        });

//        getActivity().runOnUiThread(new Runnable() {
//            @Override
//            public void run() {
//                ListAdapter listAdapter = new ListAdapter(getActivity(),newsArrayList);
//                listview.setAdapter(listAdapter); // line that breaks program
//            }
//        });


        return v;
    }
}

The OkHttpRequest successfully gets all the data and organized with Gson. This is my ListAdapter:

package com.example.firebasetestapplication;

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 androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.ArrayList;

public class ListAdapter extends ArrayAdapter<News> {


    public ListAdapter(@NonNull Context context, ArrayList<News> newsArrayList) {
        super(context,R.layout.custom_news_item,newsArrayList);
    }

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

        View listItemView = convertView;
        News news = getItem(position);

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

        ImageView club_logo = listItemView.findViewById(R.id.club_logo);
        TextView club = listItemView.findViewById(R.id.club);
        TextView club_description = listItemView.findViewById(R.id.club_description);
        TextView title = listItemView.findViewById(R.id.title);
        TextView description = listItemView.findViewById(R.id.description);
        TextView time = listItemView.findViewById(R.id.time);
        
        club_logo.setImageResource(R.drawable.frats_color); // Temporary
        club.setText(news.getClub());
        club_description.setText(news.getClub_description());
        title.setText(news.getTitle());
        description.setText(news.getDescription());
        time.setText(news.getTime());

        return listItemView;
    }
}

And my News class Model:

package com.example.firebasetestapplication;

public class News {

    String club;
    String club_description;
    String title;
    String description;
    String time;

    public News(String club, String club_description, String title, String description, String time) {
        this.club = club;
        this.club_description = club_description;
        this.title = title;
        this.description = description;
        this.time = time;
    }

    public String getClub() {return club;}
    public String getClub_description() {return club_description;}
    public String getTitle() {return title;}
    public String getDescription() {return description;}
    public String getTime() {return time;}

    public void setClub(String club) {this.club = club;}
    public void setClub_description(String club_description) {this.club_description = club_description;}
    public void setTitle(String title) {this.title = title;}
    public void setDescription(String description) {this.description = description;}
    public void setTime(String time) {this.time = time;}


}

Finally, here is my custom_news item xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp">

        <LinearLayout
            android:id="@+id/first_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginVertical="3dp">
    
            <ImageView
                android:id="@+id/club_logo"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:src="@drawable/frats_color"/>
            
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="5dp"
                android:orientation="vertical">
                
                <TextView
                    android:id="@+id/club"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="0dp"
                    android:textSize="20sp"
                    android:textColor="@color/black"
                    android:textStyle="bold"
                    android:text="Frater Sodalis" />
                <TextView
                    android:id="@+id/club_description"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Social Club at Abilene Christian University"
                    android:textStyle="italic"/>

            </LinearLayout>

        </LinearLayout>
        
        <TextView
            android:id="@+id/time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:padding="15dp"
            android:text="8:15pm" />

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/first_layout"
            android:layout_marginTop="0dp"
            android:layout_marginStart="10dp"
            android:textSize="15sp"
            android:textColor="@color/black"
            android:textStyle="bold"
            android:text="Haunted Forrest is now open! 6869 E North " />

        <TextView
            android:id="@+id/description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/title"
            android:layout_marginTop="10dp"
            android:layout_marginStart="10dp"
            android:layout_marginBottom="10dp"
            android:textSize="15sp"
            android:text="@string/HF_Example"/>


    </RelativeLayout>

</LinearLayout>

and my fragment_news xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".NewsFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/textview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textStyle="bold"
        android:text="News Fragment" />

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/listview"
        tools:listitem="@layout/custom_news_item" />

</FrameLayout>

I know if looks like a lot, but I am pretty sure that the error lies around the ListAdapter or the News Fragment. I was looking into whether the getActivity() was passing the correct context for the Fragment or whether my listview.setAdapter(listAdapter); needs a RunOnUiThread somehow in a fragment.

I would very much appreciate it if someone could give me a hint on what's missing for my listview. I know I am pretty close. Thank you so much!

Just in case you are wondering, the Main Activity looks like this:

package com.example.firebasetestapplication;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.firebasetestapplication.databinding.ActivityMainBinding;
import com.firebase.ui.database.FirebaseListAdapter;
import com.firebase.ui.database.FirebaseListOptions;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
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;

public class MainActivity extends AppCompatActivity {

    private TextView greetings;
    private Button logout;

    //Firebase
    FirebaseAuth mAuth = FirebaseAuth.getInstance();
    private FirebaseListAdapter<ChatMessage> adapter;
    private FirebaseUser user;
    private FirebaseUser currentUser;
    private DatabaseReference reference;

    // Binding
    ActivityMainBinding binding;

    //Assets
    private FloatingActionButton fab;

    private String userID;

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        replaceFragment(new HomeFragment());
//
        binding.bottomNavigationView.setOnItemSelectedListener(item -> {

            switch (item.getItemId()) {
                case R.id.home:
                    replaceFragment(new HomeFragment());
                case R.id.profile:
                    break;
                case R.id.settings:
                    break;
                case R.id.news:
//                    startActivity(new Intent(MainActivity.this, NewsActivity.class));
                    replaceFragment(new NewsFragment());
            }
            return true;
        });

        logout = findViewById(R.id.signOut);
//        greetings = findViewById(R.id.greeting);
        currentUser = mAuth.getCurrentUser();

//        fab = findViewById(R.id.fab);
//
//        fab.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
//                EditText input = findViewById(R.id.input);
//                FirebaseDatabase.getInstance()
//                        .getReference()
//                        .push()
//                        .setValue(new ChatMessage(input.getText().toString(),
//                                FirebaseAuth.getInstance()
//                                        .getCurrentUser()
//                                        .getDisplayName())
//                        );
//
//                // Clear the input
//                input.setText("");
//            }
//        });

        logout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FirebaseAuth.getInstance().signOut();
                startActivity(new Intent(MainActivity.this, LoginActivity.class));
            }
        });

        if (currentUser == null)
        {
            Intent intent
                    = new Intent(MainActivity.this,
                    LoginActivity.class);
            startActivity(intent);
        }
        else
        {
//            displayChatMessages();

            user = FirebaseAuth.getInstance().getCurrentUser();
            reference = FirebaseDatabase.getInstance().getReference("Users");
            userID = user.getUid();

            reference.child(userID).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    User userChat = snapshot.getValue(User.class);
                    if(userChat != null) {
                        String fullname = userChat.fullName;
                        String email = userChat.email;
                        String age = userChat.age;

//                        greetings.setText("Welcome, " + fullname + "!");
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {
                    Toast.makeText(MainActivity.this, "Something did not go right!", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    private void replaceFragment(Fragment fragment) {

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.frame_layout, fragment);
        fragmentTransaction.commit();
    }
}

0 Answers0