Reputation: 1515
I have a CustomWidget called CalenderItem
. It has two TextView
s in it and an OnClickListener
.
This is the xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/background_calender_item"
android:clickable="true"
android:focusable="true">
<TextView
android:id="@+id/text_view_calender_item_date"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/text_view_calender_item_routine"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
And this is the Java Code:
public class CalenderItem extends LinearLayout {
public CalenderItem(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater l = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
l.inflate(R.layout.calender_item, this, true);
setLayoutParams(new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 1)); //TableRow, because I use it as a child inside a TableRow.
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(listener != null) {
listener.itemClicked(day, month, year);
}
}
});
}
public interface IItemClicked {
void itemClicked(int day, int month, int year);
}
private IItemClicked listener = null;
public void setOnItemClickedListener(IItemClicked listener) {
this.listener = listener;
}
}
At first, I haven't set clickable
and focusable
to true
in the xml. The OnClickListener
got triggered, the ripple effect (which I made with a custom background drawable) didn't work. So, I set clickable
and focusable
to true. Now, the OnClickListener doesn't work anymore.
I have tried setting android:duplicateParentState="true"
and I have also tried setting clickable
to false inside every child, but it didn't work either.
I have also tried setting an OnTouchListener
inside the Java code instead of an OnClickListener
, which resulted in the ripple effect not working.
EDIT Edited the full class code
EDIT 2 Following the answer by @Md. Asaduzzaman, I gte the following Logcat:
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] JNI ERROR (app bug): local reference table overflow (max=512)
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] local reference table dump:
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] Last 10 entries (of 512):
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 511: 0x131ddc00 com.workoutlog.workoutlog.views.CalenderItem
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 510: 0x131dd800 com.workoutlog.workoutlog.views.CalenderItem
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 509: 0x131dd400 com.workoutlog.workoutlog.views.CalenderItem
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 508: 0x131d4c00 com.workoutlog.workoutlog.views.CalenderItem
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 507: 0x131d4800 com.workoutlog.workoutlog.views.CalenderItem
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 506: 0x131d4400 com.workoutlog.workoutlog.views.CalenderItem
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 505: 0x131d4000 com.workoutlog.workoutlog.views.CalenderItem
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 504: 0x131d3c00 com.workoutlog.workoutlog.views.CalenderItem
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 503: 0x131d3800 com.workoutlog.workoutlog.views.CalenderItem
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 502: 0x131d3400 com.workoutlog.workoutlog.views.CalenderItem
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] Summary:
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 1 of com.workoutlog.workoutlog.views.Calender
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 504 of com.workoutlog.workoutlog.views.CalenderItem (504 unique instances)
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 2 of java.lang.Class (2 unique instances)
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 4 of java.lang.String (4 unique instances)
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138] 1 of java.lang.String[] (4 elements)
2019-10-17 10:44:08.444 510-510/com.workoutlog.workoutlog A/art: art/runtime/indirect_reference_table.cc:138]
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] Runtime aborting...
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] Aborting thread:
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] "main" prio=5 tid=1 Runnable
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] | group="" sCount=0 dsCount=0 obj=0x77c16c50 self=0x78f10a1a00
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] | sysTid=510 nice=0 cgrp=default sched=1073741825/1 handle=0x78f51f0a98
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] | state=R schedstat=( 1101401050 13378120 491 ) utm=97 stm=13 core=7 HZ=100
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] | stack=0x7ff30b0000-0x7ff30b2000 stackSize=8MB
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] | held mutexes= "abort lock" "mutator lock"(shared held)
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.RenderNode.create(RenderNode.java:161)
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.View.<init>(View.java:4023)
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.View.<init>(View.java:4137)
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.ViewGroup.<init>(ViewGroup.java:578)
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.widget.LinearLayout.<init>(LinearLayout.java:214)
2019-10-17 10:44:09.726 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.widget.LinearLayout.<init>(LinearLayout.java:210)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at com.workoutlog.workoutlog.views.CalenderItem.<init>(CalenderItem.java:52)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at com.workoutlog.workoutlog.views.CalenderItem.<init>(CalenderItem.java:48)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at java.lang.reflect.Constructor.newInstance0!(Native method)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.LayoutInflater.createView(LayoutInflater.java:656)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:798)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:738)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.LayoutInflater.inflate(LayoutInflater.java:495)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] - locked <0x0675666f> (a java.lang.Object[])
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at com.workoutlog.workoutlog.views.CalenderItem.<init>(CalenderItem.java:66)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at com.workoutlog.workoutlog.views.CalenderItem.<init>(CalenderItem.java:48)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at java.lang.reflect.Constructor.newInstance0!(Native method)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.LayoutInflater.createView(LayoutInflater.java:656)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:798)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:738)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.LayoutInflater.inflate(LayoutInflater.java:495)
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] - locked <0x0675666f> (a java.lang.Object[])
2019-10-17 10:44:09.727 510-510/com.workoutlog.workoutlog A/art: art/runtime/runtime.cc:408] at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
This goes on for a while. I have implemented CalenderItem
only once. I added it as a child to a TableRow.
Upvotes: 0
Views: 93
Reputation: 15423
That isn't the correct way to implement a custom View class. In your implementation of the CalenderItem class, you're actually creating an additional LinearLayout that is not needed.
First, Define custom attribute for your CalendarItem in values/attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CalenderItem">
<attr name="calenderItemDate" format="string" />
<attr name="calenderItemRoutine" format="string" />
</declare-styleable>
</resources>
Then, implement your CalenderItem class that extends LinearLayout.
public class CalenderItem extends LinearLayout {
private String dateLabel = "";
private String routineLabel = "";
private TextView dateTextView;
private TextView routineTextView;
private IItemClicked listener = null;
public CalenderItem(Context context) {
this(context, null);
}
public CalenderItem(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CalenderItem(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.CalenderItem, 0, 0);
try {
// get the text and colors specified using the names in attrs.xml
dateLabel = a.getString(R.styleable.CalenderItem_calenderItemDate);
routineLabel = a.getString(R.styleable.CalenderItem_calenderItemRoutine);
} finally {
a.recycle();
}
LayoutInflater.from(context).inflate(R.layout.calender_item, this);
dateTextView = this.findViewById(R.id.text_view_calender_item_date);
dateTextView.setText(dateLabel);
routineTextView = this.findViewById(R.id.text_view_calender_item_routine);
routineTextView.setText(routineLabel);
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(listener != null)
listener.itemClicked(0, 0, 0);
}
});
}
public interface IItemClicked {
void itemClicked(int day, int month, int year);
}
public void setOnItemClickedListener(IItemClicked listener) {
this.listener = listener;
}
}
And Then, reference it in your XML layout like such:
<?xml version="1.0" encoding="utf-8"?>
<com.package.name.CalenderItem xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
app:calenderItemDate="2019-10-18"
app:calenderItemRoutine="Hello"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.package.name.CalenderItem>
Upvotes: 0
Reputation: 76
Edited:
Well, This is not the correct way to implement custom view.
Please refer to this answer
Upvotes: 1