0

I'm wondering if someone could help me to fix this error with Intent?

I have 2 activities to connect between the: The first activity for Grid View "MainActivity.kt", second for List View "Main2Activity.kt"and I have 2 object instance (adapter1,adapter2) from "Main2Activity.kt" and I wanna pass specific object instance (adapter1) or (adapter2) when click on specific image in the "MainActivity.kt"

Note: I'm using BaseAdapter

Here is a MainActivity.kt

class MainActivity : AppCompatActivity() {

var adapter:FoodAdapter?=null
var listOfFoods =ArrayList<Food>()
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(layout.activity_main)


    // load foods
    listOfFoods.add(Food("Coffee","   Coffee preparation is", a))
    listOfFoods.add(Food("Coffee","   Coffee preparation is", b))
    listOfFoods.add(Food("Coffee","   Coffee preparation is", c))
    listOfFoods.add(Food("Coffee","   Coffee preparation is", d))

    adapter= FoodAdapter(this,listOfFoods)

    gvListFood.adapter =adapter

}


class  FoodAdapter: BaseAdapter {
    var listOfFood= ArrayList<Food>()
    var context: Context?=null
    constructor(context:Context,listOfFood:ArrayList<Food>):super(){
        this.context=context
        this.listOfFood=listOfFood
    }
    override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View? {
        val food = this.listOfFood[p0]
        var inflator = context!!.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        var foodView= inflator.inflate(layout.food_ticket,null)
        foodView.ivFoodImage.setImageResource(food.image!!)
        foodView.ivFoodImage.setOnClickListener {


            if (foodView.ivFoodImage.context!!.equals(a) ) {
                val intent = Intent(context, Main2Activity::class.java)
                intent.putExtra(Main2Activity.EXTRA_ADAPTER_MODE, AdapterType.ADAPTER_TYPE_2.ordinal)
                    intent.putExtra("name", food.name!!)
                    intent.putExtra("des", food.des!!)
                    intent.putExtra("image", food.image!!)

                    context!!.startActivity(intent)

            }
            else if (foodView.ivFoodImage.context!!.equals(b)) {
                val intent = Intent(context, Main2Activity::class.java)
                intent.putExtra(Main2Activity.EXTRA_ADAPTER_MODE, AdapterType.ADAPTER_TYPE_2.ordinal)
                    intent.putExtra("name", food.name!!)
                    intent.putExtra("des", food.des!!)
                    intent.putExtra("image", food.image!!)
                    context!!.startActivity(intent)

           }
        }
        return foodView
    }

    override fun getItem(p0: Int): Any {
        return listOfFood[p0]
    }

    override fun getItemId(p0: Int): Long {
        return p0.toLong()
    }

    override fun getCount(): Int {

        return listOfFood.size
    }

}
}

Here is a Main2Activity.kt

class Main2Activity : AppCompatActivity() {
companion object {
    val EXTRA_ADAPTER_MODE = "extra_adapter_mode"
}
var adapter1: FoodAdapter? = null
var adapter2: FoodAdapter2? = null
var listOfFoods2 = ArrayList<Food>()
var listOfFoods3 = ArrayList<Food>()
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main2)


    val bundle = intent?.getIntExtra(EXTRA_ADAPTER_MODE, AdapterType.ADAPTER_TYPE_1.ordinal)
    val name = bundle?.let { AdapterType.fromOrdinal(it) }
    val des = bundle?.let { AdapterType.fromOrdinal(it) }
    val image = bundle?.let { AdapterType.fromOrdinal(it) }

    //val bundle = intent.extras
    //val name = bundle.getString("name")
    //val des = bundle.getString("des")
    //val image = bundle.getInt("image")



    /*
    ivFoodImage2?.let {
        it.setImageResource(image)
    }

    tvName2?.let {
        it.text = name
    }

    tvDes2?.let {
        it.text = des
    }
    */





    // load foods2
    listOfFoods2.add(Food("Coffee", "   Coffee1 preparation is", R.drawable.a))
     listOfFoods2.add(Food("Coffee", "   Coffee2 preparation is", R.drawable.b))

         //listOfFoods2.add(Food("Coffee","   Coffee preparation is",R.drawable.c))
         //listOfFoods2.add(Food("Coffee","   Coffee preparation is",R.drawable.d))


    // load foods3


    //listOfFoods3.add(Food("Coffee","   Coffee preparation is",R.drawable.a))
    //listOfFoods3.add(Food("Coffee","   Coffee preparation is",R.drawable.b))
    listOfFoods3.add(Food("Coffee", "   Coffee3 preparation is", R.drawable.c))
    listOfFoods3.add(Food("Coffee", "   Coffee4 preparation is", R.drawable.d))



   if(adapter1 ==lvFoods2.adapter) {
       adapter1 = FoodAdapter(listOfFoods2, this)
       lvFoods2.adapter = adapter1
    } else if (adapter2==lvFoods2.adapter) {
       adapter2 = FoodAdapter2(listOfFoods3, this)
       lvFoods2.adapter = adapter2
     }

    }


class FoodAdapter : BaseAdapter {
    var context: Context? = null
    var listOfFoodsLocal2 = ArrayList<Food>()

  constructor(listOfFoods2: ArrayList<Food>, context: Context) : super() {
        this.listOfFoodsLocal2 = listOfFoods2
        this.context = context
    }

    override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
        val food = this.listOfFoodsLocal2[p0]
        var inflator = context!!.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val foodView = inflator.inflate(R.layout.food_ticket2, null)


                 foodView.ivFoodImage2?.let {
                     it.setImageResource(food.image!!)
                 }
        foodView.tvName2?.let {

            it.text = food.name!!
        }
        foodView.tvDes2?.let {
            it.text = food.des!!
        }

        foodView.ivFoodImage2.setOnClickListener {

            //move to next
            val intent = Intent(context, FoodDetails::class.java)
            intent.putExtra("name", food.name!!)
            intent.putExtra("des", food.des!!)
            intent.putExtra("image", food.image!!)

            context!!.startActivity(intent)

        }
        return foodView

    }


    override fun getItem(p0: Int): Any {
        return listOfFoodsLocal2[p0]
    }

    override fun getItemId(p0: Int): Long {
        return p0.toLong()
    }

    override fun getCount(): Int {
        return listOfFoodsLocal2.size
    }

}

class FoodAdapter2 : BaseAdapter {
    var context: Context? = null
    var listOfFoodsLocal3 = ArrayList<Food>()

  constructor(listOfFoods3: ArrayList<Food>, context: Context) : super() {
        this.listOfFoodsLocal3 = listOfFoods3
        this.context = context
    }

    override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
        val food = this.listOfFoodsLocal3[p0]
        var inflator = context!!.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val foodView = inflator.inflate(R.layout.food_ticket2, null)


         foodView.ivFoodImage2?.let {
             it.setImageResource(food.image!!)
         }
        foodView.tvName2?.let {
            it.text = food.name!!
        }
         foodView.tvDes2?.let {
             it.text = food.des!!
         }



        foodView.ivFoodImage2.setOnClickListener {

            //move to next
            val intent = Intent(context, FoodDetails::class.java)
            intent.putExtra("name", food.name!!)
            intent.putExtra("des", food.des!!)
            intent.putExtra("image", food.image!!)

            context!!.startActivity(intent)

        }
        return foodView

    }


    override fun getItem(p0: Int): Any {
        return listOfFoodsLocal3[p0]
    }

    override fun getItemId(p0: Int): Long {
        return p0.toLong()
    }

    override fun getCount(): Int {
        return listOfFoodsLocal3.size
    }

}
}

Here is enum class

enum class AdapterType {
ADAPTER_TYPE_1,
ADAPTER_TYPE_2,
ADAPTER_TYPE_3;


companion object {
     fun fromOrdinal(name:String,des:String,image: Int): AdapterType? {
        return AdapterType.values().firstOrNull { it.ordinal == image}



     }
}
}
MB_Coder
  • 765
  • 1
  • 7
  • 14
  • I don't think that this code will compile, does it? In your intent you specify the Activity you want to go to. You cannot specify adapters. Put another boolean into the intent and decide in Activity 2 according to the boolean what adapter to use... – luckyhandler Sep 23 '17 at 21:29
  • thank you @Nino Handler, yes, my code doesn't compile – MB_Coder Sep 24 '17 at 00:51
  • boolean accept true or false, Actually in Activity 2 i wanna add more than 2 adapter not only 2 its like 50 adapter(each adapter has different ArrayList) so how can i do that without specify adapters – MB_Coder Sep 24 '17 at 01:32
  • you could specify an @IntDef https://developer.android.com/reference/android/support/annotation/IntDef.html and pass the int with the bundle and then use a switch case statement to determine which adapter to use – luckyhandler Sep 24 '17 at 06:17

2 Answers2

2

Create an IntDef like:

@Retention(SOURCE)
@IntDef({ADAPTER_MODE_1, ADAPTER_MODE_2, ADAPTER_MODE_3})
public @interface AdapterMode {}
public static final int ADAPTER_MODE_1 = 0;
public static final int ADAPTER_MODE_2 = 1;
public static final int ADAPTER_MODE_3 = 2;
//...

and add the int to the bundle. For Kotlin you have to use a companion object to define the variables like

class FirstActivity {
    companion object { 
         val ADAPTER_MODE1 = 0
         val ADAPTER_MODE2 = 1
         val ADAPTER_MODE3 = 2
         //...
    }
}

So you can pass unlimited adapter cases to your 2nd activity

EDIT: Kotlin doesn't support @IntDef so you should use an enum for that:

enum class AdapterType {
    ADAPTER_TYPE_1,
    ADAPTER_TYPE_2,
    ADAPTER_TYPE_3;

    companion object {
        fun fromOrdinal(ordinal: Int): AdapterType? {
            return AdapterType.values().firstOrNull { it.ordinal == ordinal }
        }
    }
}

Then use it like:

class FirstActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val intent = Intent(this, SecondActivity::class.java)
        intent.putExtra(SecondActivity.EXTRA_ADAPTER_MODE, AdapterType.ADAPTER_TYPE_2.ordinal)
    }
}

And retrieve it like:

class SecondActivity : AppCompatActivity() {
    companion object {
        val EXTRA_ADAPTER_MODE = "extra_adapter_mode"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //...
        val adapterTypeOrdinal = intent?.getIntExtra(EXTRA_ADAPTER_MODE, AdapterType.ADAPTER_TYPE_1.ordinal)
        val adapterType = adapterTypeOrdinal?.let { AdapterType.fromOrdinal(it) }

        // do something with it
    }
}
luckyhandler
  • 10,651
  • 3
  • 47
  • 64
  • thank you @Nino Handler for answer, Actually i create an "IntDef" and my question code been updated, in the second part of your answer : please can you help me because i don't know how to add the int to the bundle, and where to add your companion object code inside my 2nd activity please can you check my 2nd activity – MB_Coder Sep 25 '17 at 00:05
  • I updated my answer as Kotlin does not support @IntDef which I didn't know. So read it from the EDIT part on. And update your question – luckyhandler Sep 25 '17 at 12:06
  • Thank you @Nino Handler, I did it, but this is my first time using enum,please can you check my question code its updated because its not done yet – MB_Coder Sep 26 '17 at 04:27
  • I got problem with enum class by using companion object because i have 3 parameter (name:String,des:String,image:Int) and i dont know how to do it, and i have problem with 2nd activity. note: I have food class for constructor – MB_Coder Sep 26 '17 at 04:37
  • @Marzadmz if you have problems with an enum you should open another question – luckyhandler Sep 26 '17 at 04:50
  • the enum is only for the adapters not for anything else. – luckyhandler Sep 26 '17 at 04:52
  • thank you so much, Actually i did another question but i didn't get any answer, please can you help me and this is my link [link](https://stackoverflow.com/questions/46461348/applyinga-enum-consist-of-3-adapters-between-2-activities-in-kotlin) – MB_Coder Sep 29 '17 at 00:02
1

You can not pass Adapters between Activities. At least in a clean way, recommended by Google. Adapters implement neither Parcelable nor Serializable interface. So general rule, as Nino Handler pointed out - use Intent to send data (not Adapters itself) which should be used to create Adapter.

Mike
  • 2,547
  • 3
  • 16
  • 30