My app is basically a simple To Do list - users can add items, check them off, and delete. Deletion happens by tapping the list item. Adding and checking off items work perfectly. However, I cannot get single tapping to work.
I have tried blocking focusability, and it does not help.
package com.example.p10_studio_version;
import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
public class TodoActivity extends Activity {
private static final String DEBUG_TAG = "OurLog: Gestures/ToDo";
Button addButton;
EditText textEditor;
String neededGesture;
String signifierTiming;
DbHelper dbHelper;
ListView listView;
ArrayAdapter<String> adapter;
String errormMessage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_todo);
addButton = findViewById(R.id.add_button);
textEditor = findViewById(R.id.entry_input);
dbHelper = new DbHelper(this);
dbHelper = new DbHelper(this);
listView = findViewById(R.id.list_view);
showItemList();
addButton.setOnClickListener(new OnClickListener(){
public void onClick(View view){
String text = textEditor.getText().toString();
System.out.println("OurLog: AddEntry button click");
if (!text.equals("")){
textEditor.setText("");
dbHelper.insertNewItem(text);
showItemList();
System.out.println("OurLog: ListItem added");
} else {
textEditor.setText(errormMessage); //change later
//emptyToast.show(); //error toast
System.out.println("OurLog: Attempt at adding ListItem, but field was empty.");
}
System.out.println("OurLog: AddEntry button click");
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//The code never seems to reach this point
System.out.println("++++++ I am single tapping ++++++++++++");
deleteListItem(view);
}
});
public void deleteListItem(View view) {
TextView tv = view.findViewById(R.id.item_text);
String itemText = String.valueOf((tv).getText());
dbHelper.deleteItem(itemText);
showItemList();
System.out.println("OurLog: deleteListItem deleted a ListItem");
}
private void showItemList() {
ArrayList<String> itemList = dbHelper.getTodoList();
if(adapter==null) {
adapter = new ArrayAdapter<>(this, R.layout.listitems, R.id.item_text, itemList);
listView.setAdapter(adapter);
}
else {
adapter.clear();
adapter.addAll(itemList);
adapter.notifyDataSetChanged();
}
}
}
activity_todo.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=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>-->
<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"
android:background="#DEDFE2"
tools:context="com.example.p10_studio_version.TodoActivity"
android:id="@+id/relativeLayout">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="10dp"
android:gravity="center"
android:text="@string/title_text"
android:textSize="50sp"
app:layout_constraintBottom_toTopOf="@+id/list_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:background="#80DF675D"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title"
android:descendantFocusability="blocksDescendants" />
<EditText
android:id="@+id/entry_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="8dp"
android:autofillHints="hi"
android:background="#B3FFFFFF"
android:gravity="bottom"
android:inputType="text"
android:padding="10dp"
app:layout_constraintBottom_toTopOf="@+id/add_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="50dp"
android:layout_marginBottom="20dp"
android:background="#DF675C"
android:text="@string/button_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.606"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<ImageView
android:id="@+id/doubletap_anim"
android:layout_width="126dp"
android:layout_height="126dp"
android:layout_marginStart="36dp"
android:layout_marginLeft="36dp"
android:layout_marginTop="332dp"
android:visibility="gone"
app:background="@drawable/animation_double"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/list_view" />
<ImageView
android:id="@+id/longtap_anim"
android:layout_width="126dp"
android:layout_height="126dp"
android:layout_marginStart="68dp"
android:layout_marginLeft="68dp"
android:layout_marginTop="332dp"
android:visibility="gone"
app:background="@drawable/animation_long"
app:layout_constraintStart_toEndOf="@id/doubletap_anim"
app:layout_constraintTop_toTopOf="@id/list_view" />
</androidx.constraintlayout.widget.ConstraintLayout>
And my dbhelper, in case someone wants to reproduce:
package com.example.p10_studio_version;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
public class DbHelper extends SQLiteOpenHelper {
public static final String DB_NAME = "ToDoDB";
public static final String TABLE_NAME = "ItemsToDo";
public static final String COLUMN_NAME = "Items";
public static final int DB_VERSION = 1;
public DbHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String query = String.format("CREATE TABLE %s (ID INTEGER PRIMARY KEY AUTOINCREMENT, %s TEXT NOT NULL);", TABLE_NAME, COLUMN_NAME);
db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String query = String.format("DELETE TABLE IF EXISTS %s", TABLE_NAME);
db.execSQL(query);
onCreate(db);
}
public void insertNewItem(String item) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values= new ContentValues();
values.put(COLUMN_NAME, item);
db.insertWithOnConflict(TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.close();
}
public void deleteItem(String item) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, COLUMN_NAME + " = ?", new String[]{item});
db.close();
}
public ArrayList<String> getTodoList() {
ArrayList<String> todoList = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.query(TABLE_NAME, new String[]{COLUMN_NAME}, null, null, null, null, null);
while (c.moveToNext()) {
int index = c.getColumnIndex(COLUMN_NAME);
todoList.add(c.getString(index));
}
c.close();
db.close();
return todoList;
}
}
Is it something with the XML? Hope someone can see which obvious thing I have messed up.
Best Way to set ItemClickListener for listview is implementing interface for it.
try implementing custom listview with custom adapter and interface.
Be Aware, if you want to remove/add/.etc item from a list, it's better to use RecyclerView Instead Of ListView.