since yesterday I have tried to change the content of an imageView into a fragment but beautiful the button and it does nothing.
I would appreciate any help
Method used in the fragment:
override fun onClick(v: View?) {
when (v?.id) {
R.id.nextButton -> {
// val rnds = (0..99999).random()
val quest1 = "https://My-web-get-image-url.com/"
// var randomGetNumber = quest1 + rnds
Picasso.get().load(quest1).memoryPolicy(MemoryPolicy.NO_CACHE).into(memeRandomView)
Picasso.get().setLoggingEnabled(true)
}
else -> {
}
}
}
}
My layaout
<ImageView
android:id="#+id/memeRandomView"
android:layout_width="385dp"
android:layout_height="452dp"
android:layout_marginStart="32dp"
android:layout_marginTop="28dp"
android:layout_marginEnd="32dp"
android:src="#drawable/logo"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.578"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/memeRandomView"
app:layout_constraintVertical_bias="0.434" />
After you get a reference for your views(nextButton,memeRandomView) using findViewById(),viewBinding,kotlin-ext , you can set a click like that and use picasso in the click listener:
nextButton.setOnClickListener{
Picasso.get()
.load(url)
.centerCrop()
.into(memeRandomView)
}
Related
Spinner doesn't display items. I'm making program for inventorization now. I get data from API. And I have the problem. Spinner doesn't show items. I add items to ArrayList and then add this list to spinner adapter. I've tried a lot of thing that i found at stackoverflow and another sites. But nothing helps me.
Code:
activity_add_classes.xml:
<pre><code>
<TextView
android:id="#+id/add_class_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Добавить кабинет"
android:textAlignment="center"
android:textColor="#color/black"
android:textSize="25sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="25dp"
/>
<EditText
android:id="#+id/class_number_add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/add_class_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_margin="16dp"
android:hint="Номер класса"
android:textSize="20sp"
android:singleLine="true"
android:maxLength="3"
android:digits="1234567890"
/>
<Spinner
android:id="#+id/corps_spinner"
app:layout_constraintTop_toBottomOf="#id/class_number_add"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="#array/corps"
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="16dp"
/>
<Spinner
android:id="#+id/inventories_spinner"
android:layout_width="match_parent"
android:layout_height="75dp"
app:layout_constraintTop_toBottomOf="#id/corps_spinner"
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="16dp"
android:spinnerMode="dropdown"
app:layout_constraintEnd_toEndOf="parent"
/>
<EditText
android:id="#+id/count_of_inventory"
android:layout_width="100dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/inventories_spinner"
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="16dp"
android:maxLength="2"
android:digits="1234567890"
android:singleLine="true"
/>
<Button
android:id="#+id/add_inventory_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Добавить"
app:layout_constraintTop_toBottomOf="#id/inventories_spinner"
android:layout_margin="16dp"
app:layout_constraintEnd_toEndOf="parent"
/>
AddClassesActivity.kt:
enter code here
package com.example.inventorizationmpt
class AddClassesActivity : AppCompatActivity() {
lateinit var inventoriesSpinner: Spinner
lateinit var listInventory : ArrayList
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_classes)
listInventory = ArrayList()
inventoriesSpinner = findViewById(R.id.inventories_spinner)
getInventories()
spinAdapt()
}
fun spinAdapt(){
val spinnerAdapter = ArrayAdapter(this#AddClassesActivity, android.R.layout.simple_spinner_item,listInventory)
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinnerAdapter.notifyDataSetChanged()
inventoriesSpinner.adapter = spinnerAdapter
}
fun getInventories(){
val inventorizationService = ServiceBuilder.buildService(InventorizationService::class.java)
val requestCall = inventorizationService.getInventoriesList()
requestCall.enqueue(object : Callback>{
override fun onResponse(
call: Call>,
response: Response>
) {
if (response.isSuccessful){
val listForSpinner = response!!.body()
for (i in 0..listForSpinner!!.size - 1){
listInventory.add(
ItemOfInventory(
listForSpinner[i].id_Inventory,
listForSpinner[i].inventory_Name
)
)
}
}else {
Toast.makeText(this#AddClassesActivity, "Что-то пошло не так. Ошибка со стороны сервера", Toast.LENGTH_LONG).show()
}
}
override fun onFailure(call: Call>, t: Throwable) {
Toast.makeText(this#AddClassesActivity, "Что-то пошло не так. Ошибка со стороны сервера", Toast.LENGTH_LONG).show()
}
})
}
}
The above is what I am trying to achieve .
My recycle view item has two buttons . Both are hidden by default . On click of the item view should show the buttons for 1 sec. After it must hide . if I tap on either of these buttons , the timer should be reset for another 1 sec . Something similar to a debounce in rx java.
Need to do it with Kotlin coroutines .
I was able to achieve the above using kotlin coroutines jobs .
My layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="150dp"
android:layout_height="250dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginHorizontal="5dp"
android:elevation="5dp"
android:layout_gravity="bottom"
>
<TextView
android:id="#+id/product_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="#id/guideline_horizontal_top"
android:text="x2"
android:fontFamily="#font/gotham"
android:textColor="#color/dark_blue"
android:textSize="20sp"/>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline_horizontal_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".20"/>
<androidx.cardview.widget.CardView
android:id="#+id/part_card"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#id/guideline_horizontal_top"
app:layout_constraintBottom_toBottomOf="parent"
app:cardElevation="5dp"
android:clickable="true"
android:foreground="?attr/selectableItemBackgroundBorderless"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.google.android.material.button.MaterialButton
android:id="#+id/plus_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#color/transparent_dark_blue"
app:layout_constraintTop_toTopOf="parent"
android:insetTop="0dp"
app:cornerRadius="0dp"
android:text="ADD"
android:visibility="invisible"/>
<com.google.android.material.button.MaterialButton
android:id="#+id/minus_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#color/transparent_dark_blue"
app:layout_constraintBottom_toBottomOf="parent"
android:insetBottom="0dp"
app:cornerRadius="0dp"
android:text="REDUCE"
android:visibility="invisible"/>
<TextView
android:id="#+id/partition_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="PART 1"
android:layout_margin="5dp"
android:textColor="#color/dark_blue"
android:fontFamily="#font/gotham_thin_font"
android:textStyle="bold"
/>
<TextView
android:id="#+id/items_left"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Items left : "
android:layout_margin="5dp"
android:textColor="#color/dark_blue"
android:fontFamily="#font/gotham_thin_font"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
android:gravity="center"/>
<TextView
android:id="#+id/product_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/partition_text"
app:layout_constraintBottom_toTopOf="#id/items_left"
android:layout_margin="5dp"
android:textColor="#color/dark_blue"
android:fontFamily="#font/gotham_thin_font"
android:textStyle="bold"
android:gravity="start"
android:text="Product name here"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
My addapter
class PartitionRecycleAdapter : RecyclerView.Adapter<PartitionRecycleAdapter.ViewHolder>() {
private var partitions: List<Selection<Partition>> = listOf()
private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO)
private var buttonManage: Job? = null
fun update(partitions: List<Selection<Partition>>) {
this.partitions = partitions
notifyDataSetChanged()
}
inner class ViewHolder(val binding: PartitionRecycleItemBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(partition: Selection<Partition>, position: Int) {
binding.apply {
partitionText.text = "Part ${partition.item.number}"
productName.text = partition.item.productName
val itemsLeftVar = partition.item.currentQty - partition.qty
itemsLeft.text = "Items left : $itemsLeftVar"
productCount.text = "X${partition.qty}"
if (partition.qty > 0) {
productCount.visibility = View.VISIBLE
} else {
productCount.visibility = View.INVISIBLE
}
Log.d(TAG, "bind: OUTER")
val listener = View.OnClickListener { view ->
buttonManage?.cancel()
buttonManage = coroutineScope.launch {
Log.d(TAG, "bind: Coroutine started")
delay(1000)
withContext(Dispatchers.Main) {
binding.plusButton.visibility = View.INVISIBLE
binding.minusButton.visibility = View.INVISIBLE
Log.d(TAG, "bind: Coroutine Ended")
}
}
if (view == partCard) {
binding.plusButton.visibility = View.VISIBLE
binding.minusButton.visibility = View.VISIBLE
}
if (view == plusButton) {
Log.d(TAG, "bind: PLUS")
if (itemsLeftVar > 0) {
partition.qty++
// notifyItemChanged(position)
}
}
if (view == minusButton) {
Log.d(TAG, "bind: MINUS")
if (partition.qty > 0) {
partition.qty--
// notifyItemChanged(position)
}
}
}
partCard.setOnClickListener(listener)
plusButton.setOnClickListener(listener)
minusButton.setOnClickListener(listener)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = PartitionRecycleItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val partition = partitions[position]
holder.bind(partition, position)
}
override fun getItemCount(): Int {
return partitions.size
}
}
The problem is , when I add notifyItemChanged on my button click . Everything breaks. the button closes sometimes . sometimes not .
please help..
So I'm fairly new to Kotlin.
I am trying to create an onClickListener on an image button to open the share interface, so that the particular video from the recyclerView can be shared via SMS, etc.
I followed various tutorials on how to do this as I am trying to execute this within a fragment, and the app just keeps crashing when I try to open the fragment in question.
I get the following error
java.lang.ClassCastException: java.lang.Integer cannot be cast to android.widget.ImageButton
Here is what my fragment code looks like:
SearchFragment.kt
class SearchFragment : Fragment(), View.OnClickListener
{
private var layoutManager: RecyclerView.LayoutManager? = null
private var adapter: RecyclerView.Adapter<ClipAdapter.ViewHolder>? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View
{
val rootView = inflater.inflate(R.layout.fragment_search, container, false)
loadData()
return rootView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
val shareBtn = view.findViewById<ImageButton>(R.id.button_to_share)
shareBtn.setOnClickListener(this)
}
private fun loadData()
{
val service = TwitchServiceBuilder.buildService(TwitchService::class.java)
val requestCall = service.getClips("anerdfails")
requestCall.enqueue(object : Callback<List<Clip>>
{
override fun onResponse(
call: Call<List<Clip>>,
response: Response<List<Clip>>
)
{
if (response.isSuccessful)
{
//process data
recyclerView.layoutManager = GridLayoutManager(activity, 2)
recyclerView.adapter = ClipAdapter(response.body()!!)
} else
{
//output alert
AlertDialog.Builder(activity!!)
.setTitle("API error")
.setMessage("Response, but something went wrong ${response.message()}")
.setPositiveButton(android.R.string.ok) { _, _ -> }
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
}
}
override fun onFailure(call: Call<List<Clip>>, t: Throwable)
{
//process failure
AlertDialog.Builder(activity!!)
.setTitle("API error")
.setMessage("No response, and something went wrong $t")
.setPositiveButton(android.R.string.ok) { _, _ -> }
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
}
})
}
override fun onClick(v: View?)
{
Toast.makeText(activity, "Its toast!", Toast.LENGTH_SHORT).show()
}
}
And here are my 2 layouts for the RecyclerView:
fragment_search.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"
android:paddingStart="15dp"
android:paddingTop="?attr/actionBarSize"
android:paddingEnd="15dp"
tools:context=".ui.search.SearchFragment">
<androidx.appcompat.widget.SearchView
android:background="#drawable/search_bar"
android:id="#+id/clipSearch"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="5dp"
android:focusable="true"
android:focusableInTouchMode="true"
app:layout_constraintBottom_toTopOf="#+id/recyclerView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="75dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/clipSearch" />
</androidx.constraintlayout.widget.ConstraintLayout>
clip_layout.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="wrap_content"
tools:context=".ui.search.SearchFragment">
<VideoView
android:id="#+id/videoClip"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintDimensionRatio="w,2:3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txtTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/videoClip"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/txtChannel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/txtTitle"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/txtGame"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/txtChannel"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/txtViews"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/txtGame"
tools:ignore="HardcodedText" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:orientation="horizontal"
android:weightSum="2"
android:layout_marginTop="15dp"
app:layout_constraintTop_toBottomOf="#+id/txtViews">
<ImageButton
android:id="#+id/favouriteButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#null"
android:scaleType="fitCenter"
android:src="#drawable/ic_baseline_favorite_border_24" />
<ImageButton
android:id="#+id/button_to_share"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#null"
android:scaleType="fitCenter"
android:src="#drawable/ic_baseline_share_24" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Seems like a simple mistake on my part, but I'm pulling my hair out trying to work out what I've done wrong to cause the error on loading.
Any help would be appreciated.
I see you're trying to find the button "ShareBtn" inside the fragment which is totally wrong.
the "ShareBtn" doesn't belong to the fragment, it belongs to the viewHolder which you have created inside "ClipAdapter"
What you need to do is creating an interface inside "ClipAdapter" and create an object from it inside the Adapter
then call the method which is should the clickListener delegates the click to it
lastly, you should implement it inside the fragment and put whatever logic you want
This link will help you implement it
You are casting ID of view which is an Integer to ImageButton which is a View in this line
val shareBtn = R.id.button_to_share as ImageButton
You should use this instead
val shareBtn = findViewById<ImageButton>(R.id.button_to_share)
UPDATE
Also you should find views after fragment view got created. It means you should call `findViewById` inside `onViewCreated` and not inside `onCreateView`. If you try to find views before view of fragment gets created then you get `NullPointerException` since there is no view yet.
My click listener are not working even if I check with a Toast inside of them, it use to work but after I made a couple of change in my viewModel it stop working, I can't figure out what went wrong. This happen in my detail activity only, but work on the recyclerview that call this detail activity via intent. I'm using Viewmodel, Livedata, databinding and Room. The recyclerview and the detail view are using the same viewmodel.
This is the code of my Detail activity:
class BuyDetailActivity : AppCompatActivity() {
private lateinit var sharedViewModel: BuySharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lateinit var buy: Buy
sharedViewModel = ViewModelProviders.of(this).get(BuySharedViewModel::class.java)
val position = intent.getIntExtra("position", 0)
sharedViewModel.allBuys.observe(this, Observer<List<Buy>> { buys ->
buy = buys[position]
val binding: com.example.drake.kunuk.databinding.ActivityBuyDetailBinding =
DataBindingUtil.setContentView(this, com.example.drake.kunuk.R.layout.activity_buy_detail)
binding.buy = buy
val agentNumber = buy.agentNumber
bnvContactAgent.setOnNavigationItemSelectedListener { item ->
when (item.itemId) {
com.example.drake.kunuk.R.id.action_call -> {
val callNumberUri = Uri.parse("tel:$agentNumber")
val callIntent = Intent(Intent.ACTION_DIAL, callNumberUri)
startActivity(callIntent)
}
com.example.drake.kunuk.R.id.action_sms -> {
val smsNumberUri = Uri.parse("sms:$agentNumber")
val smsIntent = Intent(Intent.ACTION_SENDTO, smsNumberUri)
startActivity(smsIntent)
}
com.example.drake.kunuk.R.id.action_email -> {
val uriText = "mailto:xxxxxxxx#gmail.com" +
"?subject=" + Uri.encode("I'm interested in $agentNumber") +
"&body=" + Uri.encode("Hello, ")
val uri = Uri.parse(uriText)
val sendIntent = Intent(Intent.ACTION_SENDTO)
sendIntent.data = uri
startActivity(Intent.createChooser(sendIntent, "Send email"))
}
}
false
}
// set animation duration via code, but preferable in your layout files by using the animation_duration attribute
expandableTextView.setAnimationDuration(750L)
// set interpolators for both expanding and collapsing animations
expandableTextView.setInterpolator(OvershootInterpolator())
// or set them separately
expandableTextView.expandInterpolator = OvershootInterpolator()
expandableTextView.collapseInterpolator = OvershootInterpolator()
// toggle the ExpandableTextView
buttonToggle.setOnClickListener {
buttonToggle.setText(if (expandableTextView.isExpanded) com.example.drake.kunuk.R.string.more else com.example.drake.kunuk.R.string.less)
expandableTextView.toggle()
}
// but, you can also do the checks yourself
buttonToggle.setOnClickListener {
if (expandableTextView.isExpanded) {
expandableTextView.collapse()
buttonToggle.setText(com.example.drake.kunuk.R.string.more)
} else {
expandableTextView.expand()
buttonToggle.setText(com.example.drake.kunuk.R.string.less)
}
}
//Open photoView activity when clicked
ivHouseDetail.setOnClickListener {
applicationContext
.startActivity(
Intent(
applicationContext,
ViewPagerActivity::class.java
)
.putExtra("imageList", buy.propertyImage)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
)
}
})
}
}
Here's my SharedViewmodel, use by both the fragment calling the detail activity and the detail activity.
class BuySharedViewModel(application: Application) : AndroidViewModel(application) {
private val repository: BuyRepository
var allBuys: LiveData<List<Buy>>
init {
val buyDao = KunukRoomDatabase.getDatabase(application, viewModelScope).buyDao()
val buyRemote = BuyRemote()
repository = BuyRepository.getInstance(buyDao , buyRemote)
//Use async because it return a result
viewModelScope.async { getAllBuys() }
allBuys = buyDao.loadAllBuys()
}
private suspend fun getAllBuys() {
repository.getBuys()
}
}
And finally this is the xml of the detail activity:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="buy" type="com.example.drake.kunuk.data.model.Buy"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent" android:layout_width="match_parent"
>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bnvContactAgent"
android:layout_width="match_parent"
android:background="#color/colorPrimary"
app:itemIconTint="#color/colorSecondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:labelVisibilityMode="unlabeled"
app:menu="#menu/bottom_nav_contact_agent"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_bias="1.0"/>
<ScrollView
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_height="0dp" android:layout_width="0dp"
app:layout_constraintBottom_toTopOf="#+id/bnvContactAgent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".ui.buy.BuyDetailActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="230dp"
tools:srcCompat="#tools:sample/backgrounds/scenic"
android:id="#+id/ivHouseDetail"
android:scaleType="centerCrop"
android:contentDescription="#string/house"
app:imageUrl="#{buy.propertyImage}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
app:formatToUSD="#{buy.price}"
android:id="#+id/tvPriceDetail"
android:textStyle="bold"
android:textColor="#color/colorPrimaryText"
android:textSize="20sp"
tools:ignore="HardcodedText"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="#+id/ivHouseDetail" android:layout_marginStart="8dp"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:text="#{buy.address}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvAddressDetail"
android:textColor="#color/colorSecondaryText"
app:layout_constraintTop_toBottomOf="#+id/tvPriceDetail"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"/>
<TextView
android:text="#{Integer.toString(buy.numberOfRoom)}"
android:maxLength="3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvBedroom"
android:layout_marginTop="12dp"
android:textStyle="bold"
android:textColor="#color/colorPrimaryText"
app:layout_constraintTop_toBottomOf="#+id/tvAddressDetail"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content" app:srcCompat="#drawable/ic_bed"
android:id="#+id/ivBedroom"
android:contentDescription="#string/bedroom_icon"
app:layout_constraintStart_toEndOf="#+id/tvBedroom"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp" app:layout_constraintTop_toBottomOf="#+id/tvAddressDetail"/>
<TextView
android:text="#{Integer.toString(buy.numberOfBath)}"
android:maxLength="3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvBathroom"
android:textStyle="bold"
android:textColor="#color/colorPrimaryText"
app:layout_constraintStart_toEndOf="#+id/ivBedroom"
android:layout_marginStart="20dp" app:layout_constraintTop_toTopOf="#+id/ivBedroom"
android:layout_marginTop="4dp"/>
<ImageView
android:layout_width="24dp"
android:layout_height="24dp" app:srcCompat="#drawable/ic_bathtub"
android:id="#+id/imageView2"
android:contentDescription="#string/bathroom_icon"
app:layout_constraintStart_toEndOf="#+id/tvBathroom"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp" app:layout_constraintTop_toBottomOf="#+id/tvAddressDetail"/>
<TextView
android:text="#{Integer.toString(buy.numberOfCar)}"
android:maxLength="3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvGarage"
android:textStyle="bold"
android:textColor="#color/colorPrimaryText"
app:layout_constraintStart_toEndOf="#+id/imageView2"
android:layout_marginStart="20dp" app:layout_constraintTop_toTopOf="#+id/imageView2"
android:layout_marginTop="4dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content" app:srcCompat="#drawable/ic_garage"
android:id="#+id/imageView3"
android:contentDescription="#string/garage_icon"
app:layout_constraintStart_toEndOf="#+id/tvGarage"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp" app:layout_constraintTop_toBottomOf="#+id/tvAddressDetail"/>
<View
android:id="#+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider"
tools:layout_editor_absoluteY="281dp" tools:layout_editor_absoluteX="8dp"
app:layout_constraintBottom_toTopOf="#+id/tvDescTitle"
android:layout_marginBottom="4dp"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvDescTitle"
android:text="#string/description"
android:layout_marginStart="8dp"
android:layout_marginTop="24dp"
android:textStyle="bold"
android:textSize="18sp"
android:textColor="#color/colorSecondaryText"
app:layout_constraintTop_toBottomOf="#+id/imageView3"
app:layout_constraintBottom_toTopOf="#id/expandableTextView"
app:layout_constraintStart_toStartOf="parent"/>
<at.blogc.android.views.ExpandableTextView
android:text="#{buy.propertyDesc}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/expandableTextView"
android:textColor="#color/colorSecondaryText"
android:maxLines="5"
android:ellipsize="end"
app:animation_duration="750"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintTop_toBottomOf="#+id/tvDescTitle"
app:layout_constraintEnd_toEndOf="parent"/>
<com.google.android.material.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/buttonToggle"
style="#style/Widget.MaterialComponents.Button.OutlinedButton"
android:text="#string/more"
app:goneUnless="#{true}"
app:layout_constraintTop_toBottomOf="#+id/expandableTextView"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="8dp"/>
<TextView
app:photoCounter="#{buy.propertyImage}"
android:background="#99000000"
android:elevation="4dp"
android:padding="4dp"
android:textColor="#ffafffff"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="#+id/ivHouseDetail"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" tools:layout_editor_absoluteY="189dp"
tools:layout_editor_absoluteX="323dp" android:id="#+id/tvPhotoCounter"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
This code is my repository class, where I use the coroutines.
class BuyRepository (private val buyDao: BuyDao, private val buyRemote: BuyRemote) {
private val job = SupervisorJob()
private val scope = CoroutineScope(Dispatchers.Default + job)
companion object {
//For singleton instantiation
#Volatile private var instance: BuyRepository? = null
fun getInstance(buyDao: BuyDao, buyRemote: BuyRemote) =
instance ?: synchronized(this) {
instance ?: BuyRepository(buyDao, buyRemote)
.also { instance = it}
}
}
suspend fun getBuys(){
refresh()
}
private suspend fun refresh(){
val list = scope.async {buyRemote.loadBuys()}
list.await().forEach { buy -> insert(buy) }
}
//#WorkerThread
private fun insert(buy: Buy) {
buyDao.insertBuy(buy)
}
}
// toggle the ExpandableTextView
buttonToggle.setOnClickListener { // <- Set listener here
buttonToggle.setText(if (expandableTextView.isExpanded) com.example.drake.kunuk.R.string.more else com.example.drake.kunuk.R.string.less)
expandableTextView.toggle()
}
// but, you can also do the checks yourself
buttonToggle.setOnClickListener { // <- And overwritten here - seems bad
if (expandableTextView.isExpanded) {
expandableTextView.collapse()
buttonToggle.setText(com.example.drake.kunuk.R.string.more)
} else {
expandableTextView.expand()
buttonToggle.setText(com.example.drake.kunuk.R.string.less)
}
}
Looks to me like you're overwriting the click listener. So ... don't do that :)
I'm facing a problem using a Samsung J1 device here.
But the image taken is bigger than the preview one.
This is the preview that I got:
and this is the final bitmap result:
I'm calling camera view with this attributes:
<com.otaliastudios.cameraview.CameraView
android:id="#+id/camera"
app:cameraGesturePinch="zoom"
app:cameraFlash="auto"
app:cameraAutoFocusResetDelay="0"
app:cameraGestureTap="focusWithMarker"
android:keepScreenOn="true"
app:cameraPreview="glSurface"
app:cameraPictureSizeSmallest="true"
android:adjustViewBounds="true"
app:cameraGestureScrollHorizontal="exposureCorrection"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
I already tried to use cameraPictureSizeAspectRatio with 4:3 but no success with it.
Did I do something wrong?
i have same problem .
after save image from cameraview ( i use camerakit lib) , display file by convert it to bitmap in imageview .
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
cameraKitView = findViewById(R.id.camera)
val captureButton = findViewById<View>(R.id.button_capture) as Button
val imageView = findViewById<ImageView>(R.id.myImageView)
captureButton.setOnClickListener {
cameraKitView!!.captureImage { _, capturedImage ->
val savedPhoto = getOutputMediaFile()
try {
val outputStream = FileOutputStream(savedPhoto!!.path)
outputStream.write(capturedImage)
outputStream.close()
val myBitmap = BitmapFactory.decodeFile(savedPhoto.getAbsolutePath())
imageView.setImageBitmap(myBitmap)
} catch (e: java.io.IOException) {
e.printStackTrace()
}
}
}
}
and this is my layout :
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.camerakit.CameraKitView
android:id="#+id/camera"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:adjustViewBounds="true"/>
<Button
android:id="#+id/button_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="#string/save"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ImageView
android:id="#+id/myImageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="0.5"
android:adjustViewBounds="true"
android:background="#android:color/holo_blue_bright"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:contentDescription="#string/app_name" />
</android.support.constraint.ConstraintLayout>
but when show image and want to take another image, cameraview is not as scale as imageview
Solved :
just change scaleType to CentreCrop . that is it