0

In my MainActivity, if I import:

import kotlinx.android.synthetic.main.activity_main.*

I can simply find my ListView and set onItemClickListener like this:

list_view.onItemClickListener

But how can I do the same thing in non-activity class?

Edit:

fun setListViewElements() {
    list_view.adapter = arrayAdapter
    list_view.onItemClickListener = AdapterView.OnItemClickListener {}
}
Joan P.
  • 2,368
  • 6
  • 30
  • 63
  • how do tyou show your listview on screen in non-activity class? – Vladyslav Matviienko Sep 19 '18 at 10:11
  • @VladyslavMatviienko Simply by using `list_view` without anything else. And just using that import. – Joan P. Sep 19 '18 at 10:18
  • Please, show full code. And where you want to call this list_view – Andrii Turkovskyi Sep 19 '18 at 10:18
  • @VladyslavMatviienko This is my full code. I just use that import and it simply find my `ListView` without using `findViewById` or anything else. – Joan P. Sep 19 '18 at 10:19
  • @Ashvinsolanki What do you mean through "achieved with interfaces"? – Joan P. Sep 19 '18 at 10:20
  • okk.... sir what u want to do with listview in non-activity class u want to update it or etc.......... – Ashvin solanki Sep 19 '18 at 10:22
  • pass the main root view into non-activity class using constructor – Ashvin solanki Sep 19 '18 at 10:25
  • @Ashvinsolanki First I just want to simply find it and then to update or anything else. – Joan P. Sep 19 '18 at 10:25
  • You can refer to the [documentation about synthetic properties](https://kotlinlang.org/docs/tutorials/android-plugin.html) to find out how they work. – Markus Penguin Sep 19 '18 at 10:27
  • check https://stackoverflow.com/questions/10996479/how-to-update-a-textview-of-an-activity-from-another-class – Ashvin solanki Sep 19 '18 at 10:32
  • @MarkusPenguin Thanks but do you know how to solve my case? – Joan P. Sep 19 '18 at 10:35
  • @Ashvinsolanki Is the same as kelalaka's answer. – Joan P. Sep 19 '18 at 10:35
  • @Ioana P. We can't understand your problem. Just show full code of your non-activity class and describe where are you want to call this list_view – Andrii Turkovskyi Sep 19 '18 at 10:57
  • @AndreyTurkovsky Please see my updated question. I want to simply use: `list_view` as I do in my activity, ok? – Joan P. Sep 19 '18 at 11:16
  • Ok, I understand exactly place, but i have to see your non-activity class. What is it? EpoxyModel or View or something else? – Andrii Turkovskyi Sep 19 '18 at 11:20
  • @AndreyTurkovsky It's a simple plain kotlin class that contains a simple function, that in my updated answer. – Joan P. Sep 19 '18 at 11:33
  • If it's just simple class - you can't find your list_view event with findViewById. And I don't understand the reason of placing this function inside such class – Andrii Turkovskyi Sep 19 '18 at 11:37
  • @AndreyTurkovsky It's a helper class, in which I define that function that will be called from within 4-5 activity classes. I know I can use `findViewById` but my question was in the first place, how I can achieve the same thing without using it. In my MainActivity I'm not using `findViewById` at all, just simply use `list_view` and that's it. – Joan P. Sep 19 '18 at 11:39
  • I said you can't use even findViewById. If it's just helper, which you call from different activities - it can't find any view. Could you show the constructor of this helper? – Andrii Turkovskyi Sep 19 '18 at 12:20

3 Answers3

0

As said here;

You have to pass the Context reference via constructor.

public class ClassB {
   Context context;
   public ClassB(Context context){
     this.context=context;
   }

   public void Update(){
        TextView txtView = (TextView) ((Activity)context).findViewById(R.id.text);
        txtView.setText("Hello");
   }
}
Enzokie
  • 7,365
  • 6
  • 33
  • 39
kelalaka
  • 5,064
  • 5
  • 27
  • 44
0

You can pass The listView as constuctor argument of your class like this:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView listView = findViewById(R.id.listview);

        ClassExample classExample = new ClassExample(listView);

    }

And :

class ClassExample {

        ListView listView;
        public ClassExample(ListView listView){
            this.listView = listView;
        }

    }

Hope this helps

Gelldur
  • 11,187
  • 7
  • 57
  • 68
Benkerroum Mohamed
  • 1,867
  • 3
  • 13
  • 19
0

You can access views without findViewById by using the kotlin-android-extensions plugin and the LayoutContainer interface.

In your build.gradle file make sure that you apply the plugin and set the experimental flag:

apply plugin: 'kotlin-android-extensions'

androidExtensions {
    experimental = true
}

The class from which you want to access the list_view needs to implement the LayoutContainer interface. Implementing that interface means that you need to provide a container view in which your ListView can be found.

Now let's assume we have a simple layout that we use for the MainActivity:

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

    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

In our MainActivity we use this file with setContentView.

Now you can write a class that is not an activity but is able to use a view (the TextView in this example) without using findViewById:

package com.example.playground

import android.view.View
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.activity_main.*

class Demo(override val containerView: View?) : LayoutContainer {

    fun setTextViewText(text: String) {
        text_view.text = text
    }

}

The class implements LayoutContainer (this is only possible if you first enable the experimental features) and therefore needs to provide the containerView property which it gets via the constructor.

Now to use this class e.g. from an activity you will need to instantiate it and give it the view in which text_view exists (the LinearLayout with the id container in my case):

val demo = Demo(container)
demo.setTextViewText("Magic!")

You will not be able to use kotlinx.android.synthetic-magic without providing a container. Because essentially what happens in the background is that if you access list_view the extension does a findViewById.

Online you can find additional information from Kotlin about the Android plugin and about how to use the Android extensions.

Markus Penguin
  • 1,581
  • 12
  • 19