mikolaj-jalocha
mikolaj-jalocha

Reputation: 728

ConstraintLayout with ListView doesn't show any data

I've constructed a simple app that consist of a FloatingActionButton and a Snackbar. When the user clicks the FAB, the actual date should be displayed in main content of app.

Unfortunately, when I'm clicking on the FAB only the Snackbar's working. ListItems doesn't show anything.

What's wrong with my code?

MainActivity.java:

public class MainActivity extends AppCompatActivity {
    ArrayList<String> listItems = new ArrayList<String>();
    ArrayAdapter<String> adapter;
    private ListView myListView;

    @Override
    protected  void onStart() {
        super.onStart();
        myListView = findViewById(R.id.listView);
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listItems);
        myListView.setAdapter(adapter);
    }

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

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                addListItem();
                Snackbar.make(view, "Item added to list", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @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
    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;
        }

        return super.onOptionsItemSelected(item);
    }

    private void addListItem(){
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss MM/dd/yyyy", Locale.US);
        listItems.add(dateFormat.format(new Date()));
        adapter.notifyDataSetChanged();
    }
}

XML of it:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/Theme.FabExample.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/Theme.FabExample.PopupOverlay" />

    </com.google.android.material.appbar.AppBarLayout>

    <include layout="@layout/content_main" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@drawable/ic_add_entry" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Fragment's java:

public class FirstFragment extends Fragment {

    @Override
    public View onCreateView(
        LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false);
    }

    public void onViewCreated(@NonNull View view, Bundle savedState) {
        super.onViewCreated(view, savedState);
    }
}

Fragment's XML:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FirstFragment">

    <ListView
        android:id="@+id/listView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        tools:layout_editor_absoluteX="117dp"
        tools:layout_editor_absoluteY="332dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

Upvotes: 1

Views: 256

Answers (1)

Elletlar
Elletlar

Reputation: 3234

I've not run your code, but it looks pretty good overall. Items are being added to the list and adapter.notifyDataSetChanged(); is being called afterwards. But one small item, you can call add directly on the adapter and it will notify regarding the change.

Platform source code for ArrayAdapter:

public void add(@Nullable T object) {
    synchronized (mLock) {
        if (mOriginalValues != null) {
            mOriginalValues.add(object);
        } else {
            mObjects.add(object);
        }
        mObjectsFromResources = false;
    }
    if (mNotifyOnChange) notifyDataSetChanged();
}

One thing that stands out, the ListView layout does not look right:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FirstFragment">    
    <ListView
        android:id="@+id/listView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        tools:layout_editor_absoluteX="117dp"
        tools:layout_editor_absoluteY="332dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
  1. It has no height or width
  2. There are no constraints

I would suggest changing it to:

android:layout_width="match_parent"
android:layout_height="match_parent"

[Perhaps wrap_content depending on your requirements.]

Also be sure to add some constraints to your ConstraintLayout. If you're not sure, press "infer constraints" at the top of the design editor or use a simpler ViewGroup container. But the ones there now in the "tools:" namespace are only used by the Android Studio "design" tab. They are not meant for the actual device.

For example:

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"

Upvotes: 2

Related Questions