After migrating CustomSubjectSpinnerAdapter from Java to Kotlin I'm getting the next exception:
java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter view
at com.xxx.xxx.activities.about.contact.CustomSubjectSpinnerAdapter.getView(Unknown Source:2)
at android.widget.AbsSpinner.onMeasure(AbsSpinner.java:206)
at android.widget.Spinner.onMeasure(Spinner.java:614)
at androidx.appcompat.widget.AppCompatSpinner.onMeasure(AppCompatSpinner.java:438)
at android.view.View.measure(View.java:25466)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:25466)
at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1412)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.widget.ScrollView.onMeasure(ScrollView.java:452)
at android.view.View.measure(View.java:25466)
at androidx.drawerlayout.widget.DrawerLayout.onMeasure(DrawerLayout.java:1119)
at android.view.View.measure(View.java:25466)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:145)
at android.view.View.measure(View.java:25466)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:25466)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:25466)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:995)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:25466)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:25466)
at androidx.drawerlayout.widget.DrawerLayout.onMeasure(DrawerLayout.java:1119)
at android.view.View.measure(View.java:25466)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:747)
at android.view.View.measure(View.java:25466)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:3397)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:2228)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2486)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
at android.view.Choreographer.doCallbacks(Choreographer.java:796)
at android.view.Choreographer.doFrame(Choreographer.java:731)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Adapter class before migration (Java)
class CustomSubjectSpinnerAdapter extends BaseAdapter {
final private String[] subjectOptions;
private final LayoutInflater inflter;
CustomSubjectSpinnerAdapter(Context applicationContext, String[] subjectOptions) {
this.subjectOptions = subjectOptions;
inflter = (LayoutInflater.from(applicationContext));
}
@Override
public int getCount() {
return subjectOptions.length;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
{
LayoutInflater vi = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.subject_spinner_row, null);
}
View llLayout = super.getDropDownView(position, convertView, parent);
roundCorners(parent);
return llLayout;
}
private void roundCorners(ViewGroup parent) {
View container2Round = ((View)parent.getParent());
if (container2Round!=null) {
GradientDrawable gd = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
new int[] {Color.WHITE, Color.WHITE});
int radius = AWScreen.dp2px(10);
gd.setCornerRadius(radius);
container2Round.setBackground(gd);
}
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = inflter.inflate(R.layout.subject_spinner_row, null);
TextView tvSubject = view.findViewById(R.id.subject);
tvSubject.setText(subjectOptions[i]);
if (subjectOptions[i].equals("")) tvSubject.setVisibility(View.GONE);
setListItemRoundedCorners(tvSubject, i);
if (i== subjectOptions.length - 1) {
int padding = AWScreen.sp2px(10, view.getContext());
tvSubject.setPadding(padding, padding, padding, padding);
}
return view;
}
private void setListItemRoundedCorners(TextView tvSubject, int i) {
if (i==1){
tvSubject.setBackgroundResource(R.drawable.rounded_border_top);
}else{
if (i==2){
tvSubject.setBackgroundResource(R.drawable.rounded_border_bottom);
}
}
}
}
Adapter class after migration (Kotlin)
internal class CustomSubjectSpinnerAdapter(
applicationContext: Context?,
private val subjectOptions: Array<String>
) : BaseAdapter() {
private val inflter: LayoutInflater
override fun getCount(): Int {
return subjectOptions.size
}
override fun getItem(i: Int): Any {
TODO("Not yet implemented")
}
override fun getItemId(i: Int): Long {
return 0
}
override fun getDropDownView(_position: Int, _convertView: View, _parent: ViewGroup): View {
var convertView: View? = _convertView
if (convertView == null) {
val vi =
_parent.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
convertView = vi.inflate(R.layout.subject_spinner_row, null)
}
val llLayout = super.getDropDownView(_position, convertView, _parent)
roundCorners(_parent)
return llLayout
}
private fun roundCorners(parent: ViewGroup) {
val container2Round = parent.parent as View
val gd = GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(Color.WHITE, Color.WHITE)
)
val radius = AWScreen.dp2px(10)
gd.cornerRadius = radius.toFloat()
container2Round.background = gd
}
override fun getView(i: Int, view: View, viewGroup: ViewGroup): View {
var view = view
view = inflter.inflate(R.layout.subject_spinner_row, null)
val tvSubject = view.findViewById<TextView>(R.id.subject)
tvSubject.text = subjectOptions[i]
if (subjectOptions[i] == "") tvSubject.visibility = View.GONE
setListItemRoundedCorners(tvSubject, i)
if (i == subjectOptions.size - 1) {
val padding = AWScreen.sp2px(10f, view.context)
tvSubject.setPadding(padding, padding, padding, padding)
}
return view
}
private fun setListItemRoundedCorners(tvSubject: TextView, i: Int) {
if (i == 1) {
tvSubject.setBackgroundResource(R.drawable.rounded_border_top)
} else {
if (i == 2) {
tvSubject.setBackgroundResource(R.drawable.rounded_border_bottom)
}
}
}
init {
inflter = LayoutInflater.from(applicationContext)
}
}
The first is a compilation problem in getItem
override fun getItem(i: Int): Any {
return null
}
It's alerting me that "Null can not be a value of a non-null type Any"
so I've tried
override fun getItem(i: Int): Any {
TODO("Not yet implemented")
}
To -at least- make it compile, but after class in instantiated in:
private fun createSubjectSpinner() {
val contactUs = ContactUs()
val strSubject = AWLocale.getStringResourceByName("activityreportproblem_textview_subject")
val subjectOptions = arrayOf(
contactUs.leaveCommentLiteral,
contactUs.reportProblemLiteral,
contactUs.requestFeatureLiteral
)
val fullSpinnerArray =
arrayOf(strSubject, subjectOptions[0], subjectOptions[1], subjectOptions[2])
binding!!.spSubject.setOnTouchListener { v: View?, event: MotionEvent ->
if (event.action == MotionEvent.ACTION_UP) {
spinnerOnTouch(subjectOptions, binding!!.spSubject)
}
false
}
val customAdapter = CustomSubjectSpinnerAdapter(this, fullSpinnerArray)
binding!!.spSubject.adapter = customAdapter
}
The mentioned exception is thrown. Any help?
CodePudding user response:
The way Adapter works is that the convertView
might be null. That’s why in your method you check if it’s null and create a new view if it is null.
In Kotlin, you must declare this parameter as nullable, since it might be null. Also you can take advantage of the Elvis operator for more concise code:
override fun getDropDownView(position: Int, _convertView: View?, parent: ViewGroup): View {
val convertView = _convertView ?:
LayoutInflator.from(parent.context)
.inflate(R.layout.subject_spinner_row, parent, false)
val llLayout = super.getDropDownView(position, convertView, parent)
roundCorners(parent)
return llLayout
}
Likewise, if you want to be able to return null from getItem()
, you must mark the return type as nullable:
override fun getItem(i: Int): Any? {
return null
}
CodePudding user response:
override fun getItem(position: Int): Any? {
return null
}
just add "?" nullable type for the function return type ,because kotlin using nullable value unlike java and base adapter using java under the hood : Object in java is equivalent to Any? not to Any