im new on android
i try create my custom arrayadapter.
I want to access the layout variables from tmpview, but I can't do that. The man in the video I watched was doing the same and he could reach
how can i reach this variables ?
I also added "kotlin-android-extensions" to the plugins section
package com.example.burclar
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import java.security.AccessControlContext
import java.util.zip.Inflater
class myArrayAdapter(var gelencontext: Context, resource: Int,var burcAdlar: ArrayList<String>, var burcTarihler: ArrayList<String>, var burcResimler: ArrayList<Int>): ArrayAdapter<String>(gelencontext, resource){
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
var tmpview = convertView
if(tmpview == null){
tmpview = LayoutInflater.from(gelencontext).inflate(R.layout.my_list_view_element,null)
}
tmpview.burcMiniYazi = burcAdlar[position] //there is a problem "unresolved reference"
tmpview.burcMiniResim = burcResimler[position] //there is a problem "unresolved reference"
tmpview.burcMiniTarih = burcTarihler[position] //there is a problem "unresolved reference"
return tmpview!!
}
}
my_list_view_element.xml :
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">
<TextView
android:id="#+id/burcMiniYazi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:text="TextView"
android:textSize="14sp"
app:layout_constraintStart_toEndOf="#+id/burcMiniResim"
app:layout_constraintTop_toTopOf="#+id/burcMiniResim" />
<ImageView
android:id="#+id/burcMiniResim"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="#tools:sample/avatars" />
<TextView
android:id="#+id/burcMiniTarih"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="#+id/burcMiniResim"
app:layout_constraintStart_toEndOf="#+id/burcMiniResim" />
<View
android:id="#+id/divider2"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_marginTop="24dp"
android:background="?android:attr/listDivider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/burcMiniResim" />
</android.support.constraint.ConstraintLayout>
thanks
enter image description here
Related
To be as clear as possible, I'm going to show the problem with a gif.
As you can see, the text is overlapping in my emulator and I don't know how to solve it, I don't know what I'm doing wrong.
It should be displayed correctly without overlapping. What I'm doing is subscribing to changes in both LiveData and StateFlow. When I press the button, I make it change the value, but instead of changing, it seems to return both values at once (Default and Hello). Could it be that the view is not refreshing? Or could it be a problem with my emulator?
Anyway, I'll leave all the code here in case you can figure it out.
FlowsFragment.kt
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.View
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.rr.stateflow_livedata_flow_sharedflow.databinding.FragmentFlowsBinding
import kotlinx.coroutines.flow.collectLatest
class FlowsFragment : Fragment(R.layout.fragment_flows) {
private lateinit var binding: FragmentFlowsBinding
private val viewModel: FlowsViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentFlowsBinding.bind(view)
binding.btnLiveData.setOnClickListener {
viewModel.triggerLiveData()
}
binding.btnStateFlow.setOnClickListener {
viewModel.triggerStateFlow()
}
subscribeToObservables()
}
private fun subscribeToObservables() {
viewModel.liveData.observe(viewLifecycleOwner) {
binding.tvLiveData.text = it
}
lifecycleScope.launchWhenStarted {
viewModel.stateFlow.collectLatest {
binding.tvStateFlow.text = it
}
}
}
}
FlowsViewModel.kt
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.*
class FlowsViewModel : ViewModel() {
private val _liveData = MutableLiveData("Default LiveData")
val liveData: LiveData<String> = _liveData
private val _stateFlow = MutableStateFlow("Default StateFlow")
val stateFlow: StateFlow<String> = _stateFlow.asStateFlow()
fun triggerLiveData() {
_liveData.value = "Hello LiveData!"
}
fun triggerStateFlow() {
_stateFlow.value = "Hello StateFlow!"
}
}
fragment_flows.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"
tools:context=".FlowsFragment">
<TextView
android:id="#+id/tvLiveData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:fontFamily="sans-serif-condensed"
android:text="Hello World!"
android:textColor="#color/black"
android:textSize="34sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/btnLiveData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="LIVEDATA"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tvLiveData" />
<TextView
android:id="#+id/tvStateFlow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:fontFamily="sans-serif-condensed"
android:text="Hello World!"
android:textColor="#color/black"
android:textSize="34sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btnLiveData" />
<Button
android:id="#+id/btnStateFlow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="STATEFLOW"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tvStateFlow" />
<TextView
android:id="#+id/tvFlow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:fontFamily="sans-serif-condensed"
android:text="Hello World!"
android:textColor="#color/black"
android:textSize="34sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.504"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btnStateFlow" />
<Button
android:id="#+id/btnFlow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="FLOW"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tvFlow" />
<TextView
android:id="#+id/tvSharedFlow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:fontFamily="sans-serif-condensed"
android:text="Hello World!"
android:textColor="#color/black"
android:textSize="34sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btnFlow" />
<Button
android:id="#+id/btnSharedFlow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="SHAREDFLOW"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tvSharedFlow" />
</androidx.constraintlayout.widget.ConstraintLayout>
I hope that the text doesn't overlap and returns the latest value of LiveData and StateFlow.
Edit with more info: The application displays the view directly from the fragment, MainActivity only has a fragment container that I show below.
MainActivity.kt
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.fragment.app.add
import androidx.fragment.app.commit
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager.commit {
setReorderingAllowed(true)
add<FlowsFragment>(R.id.mainActivityFragmentContainer)
}
}
}
activity_main.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"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/mainActivityFragmentContainer"
android:name="com.rr.stateflow_livedata_flow_sharedflow.FlowsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="#layout/fragment_flows" />
</androidx.constraintlayout.widget.ConstraintLayout>
EDIT This is not the solution, it's a bad way to solve the problem.
I just have to add this line of code in fragment_flows.xml.
android:background="#color/white"
Just by setting the background of the fragment to white, the text is no longer duplicated and overlapping.
Does anyone know why this happens? Why does what is drawn on the screen stick to the background if there is no background in the fragment layout?
Is anyone aware of how to position the buttons vertically if the button text is too long inside of the xml?
I want the buttons to be positioned horizontally if they fit, if one of the buttons has to hyphenate, then I would like to avoid that by positioning the buttons below each other. Is there a way to do it inside of the XML only?
Thanks!
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/tv_header"
style="#style/TitleTextAppearance.WithPrimaryBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/header_enter_startcode" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/dialog_background_with_margin">
<TextView
android:id="#+id/tv_status"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/pls_enter_startcode"
android:textSize="#dimen/text_size_default"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/til_startcode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="#dimen/grid_2"
app:helperText="#string/example_startcode"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv_status">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/tiet_startcode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
android:maxLines="1"
android:textStyle="bold" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.constraintlayout.widget.Guideline
android:id="#+id/gl_middle"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintGuide_percent="0.5"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="#+id/btn_continue"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/grid_2"
android:layout_marginTop="#dimen/grid_2"
android:layout_marginEnd="#dimen/grid_2"
android:text="#string/btn_continue"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/gl_middle"
app:layout_constraintTop_toBottomOf="#+id/til_startcode" />
<com.google.android.material.button.MaterialButton
android:id="#+id/btn_cancel"
style="?materialButtonOutlinedStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/grid_2"
android:layout_marginTop="#dimen/grid_2"
android:layout_marginEnd="#dimen/grid_2"
android:text="#string/cancel"
app:layout_constraintEnd_toStartOf="#+id/gl_middle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/til_startcode" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
I was able to solve this problem by creating a custom view which extends ConstraintLayout Flow. (Kudos #guglhupf for suggestion).
This should also adapt to when Foldable device is being folded.
Kotlin
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.widget.Button
import androidx.constraintlayout.helper.widget.Flow
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.allViews
import androidx.core.view.updateLayoutParams
internal class FlexLayout(context: Context, attrs: AttributeSet) : Flow(context, attrs) {
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
makeChildrenMatchParentIfTheyArePositionedVertically()
}
private fun makeChildrenMatchParentIfTheyArePositionedVertically() {
allViews.forEach { flexLayoutCandidate ->
(flexLayoutCandidate as? FlexLayout)?.let { flexLayout ->
val mutableMapOfYCoordinatesAndView = mutableMapOf<View, Int>()
//Check all the Id's that Flow layout is referencing and store them in a map
flexLayout.referencedIds.forEach { referenceId ->
val foundView = rootView.findViewById<View>(referenceId)
if (foundView != null) {
val locationOnScreen = IntArray(size = 2)
foundView.getLocationOnScreen(locationOnScreen)
Log.d("FlexLayout", "Name ${(foundView as? Button)?.text}")
Log.d("FlexLayout", "Location on screen: x = ${locationOnScreen[0]} y = ${locationOnScreen[1]}")
mutableMapOfYCoordinatesAndView[foundView] = locationOnScreen[1]
}
}
var previousMapEntry: Map.Entry<View, Int>? = null
mutableMapOfYCoordinatesAndView.forEach loopToCompareWhetherTheYCoordinatesAreDifferent#{
val currentMapEntry = it
if (previousMapEntry == null) {
previousMapEntry = currentMapEntry
return#loopToCompareWhetherTheYCoordinatesAreDifferent
}
//Check if Flow layout decided to put the view on the next line
if (previousMapEntry?.value != currentMapEntry.value) {
previousMapEntry?.key?.updateLayoutParams<ConstraintLayout.LayoutParams> {
width = ConstraintLayout.LayoutParams.MATCH_PARENT
}
currentMapEntry.key.updateLayoutParams<ConstraintLayout.LayoutParams> {
width = ConstraintLayout.LayoutParams.MATCH_PARENT
}
}
previousMapEntry = currentMapEntry
}
}
}
}
}
XML
<company.name.customview.FlexLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="#dimen/margin_between_view_blocks"
app:constraint_referenced_ids="btn_dialog_negative, btn_dialog_positive"
app:flow_horizontalGap="#dimen/space_between_two_buttons"
app:flow_horizontalStyle="spread_inside"
app:flow_verticalGap="#dimen/space_between_two_buttons"
app:flow_wrapMode="aligned"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#id/tv_dialog_body"
app:layout_constraintStart_toStartOf="#id/tv_dialog_body"
app:layout_constraintTop_toBottomOf="#+id/tv_dialog_body" />
You can put the elements in a Flow helper and configure it to automatically wrap. Remove the unnecessary constraints from btn_continue and btn_cancel
<androidx.constraintlayout.helper.widget.Flow
android:id="#+id/flow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/grid_2"
android:layout_marginStart="#dimen/grid_2"
android:layout_marginEnd="#dimen/grid_2"
app:constraint_referenced_ids="btn_continue,btn_cancel"
app:flow_horizontalGap="#dimen/grid_2"
app:flow_horizontalStyle="spread"
app:flow_wrapMode="aligned"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/til_startcode" />
<com.google.android.material.button.MaterialButton
android:id="#+id/btn_continue"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/btn_continue"/>
<com.google.android.material.button.MaterialButton
android:id="#+id/btn_cancel"
style="?materialButtonOutlinedStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/cancel" />
I have a recyclerview with adapter (to show external strings)and I'm trying to click a button "copy" so that it copies the strings in view to the clipboard.
CardLayout.xml Button to use as copy button is android:id="#+id/copyactivity"
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="0dp"
app:cardBackgroundColor="#color/white"
app:cardCornerRadius="0dp"
app:cardElevation="0dp"
app:cardMaxElevation="3dp"
app:cardPreventCornerOverlap="true"
app:cardUseCompatPadding="true"
tools:context="ui.CardLayout">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/idActivityName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="14dp"
android:layout_marginRight="10dp"
android:text="#string/placeholdertasktitle"
android:textColor="#color/black"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/idActivityDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/idActivityName"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="30dp"
android:drawablePadding="2dp"
android:text="#string/let_s_get_started_creating_a_photo_album_for_you_so_you_can_share_with_the_kids_in_the_near_future"
android:textColor="#color/black"
android:textSize="15sp"
tools:ignore="UnknownId" />
<View
android:id="#+id/divider"
android:layout_width="380dp"
android:layout_height="2dp"
android:layout_below="#id/idActivityDescription"
android:layout_alignStart="#id/idActivityName"
android:layout_centerHorizontal="false"
android:layout_centerVertical="false"
android:background="#EDEDED" />
<Button
android:id="#+id/saves"
style="#style/cardbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/divider"
android:layout_alignStart="#id/idActivityName"
android:background="#drawable/cardbutton"
android:contentDescription="#string/saves"
android:stateListAnimator="#null"
android:text="Save"
android:textAlignment="textStart"
android:textColor="#595959"
android:textSize="12sp"
app:icon="#drawable/ic_saves_blank"
app:iconGravity="textStart"
app:iconTint="#595959" />
<Button
android:id="#+id/calendar"
style="#style/cardbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/divider"
android:layout_marginStart="35dp"
android:layout_marginEnd="35dp"
android:layout_toStartOf="#+id/copyactivity"
android:layout_toEndOf="#id/saves"
android:background="#drawable/cardbutton"
android:contentDescription="#string/saves"
android:stateListAnimator="#null"
android:text="#string/calendar"
android:textAlignment="textStart"
android:textColor="#595959"
android:textSize="12sp"
app:icon="#drawable/ic_calendar"
app:iconGravity="textStart"
app:iconTint="#595959" />
<Button
android:id="#+id/copyactivity"
style="#style/cardbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/divider"
android:layout_alignEnd="#id/divider"
android:background="#drawable/cardbutton"
android:contentDescription="#string/saves"
android:stateListAnimator="#null"
android:text="#string/copy"
android:textAlignment="textStart"
android:textColor="#595959"
android:textSize="12sp"
app:icon="#drawable/ic_copytext"
app:iconGravity="textStart"
app:iconTint="#595959" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
And this is my TaskAdapter.kt
package com.example.what2do_v6.Adapter
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context.CLIPBOARD_SERVICE
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.ContextCompat.getSystemService
import androidx.recyclerview.widget.RecyclerView
import com.example.what2do_v6.Model.TaskResponse
import com.example.what2do_v6.R
import com.example.what2do_v6.Repository.TaskRepository
import com.example.what2do_v6.databinding.CardLayoutBinding
import com.example.what2do_v6.ui.CardLayout
import android.content.Context as ContentContext
class TaskAdapter: RecyclerView.Adapter<TaskAdapter.TaskViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = CardLayoutBinding.inflate(layoutInflater, parent, false)
return TaskViewHolder(binding)
}
override fun onBindViewHolder(holder: TaskViewHolder, position: Int) {
holder.bind(TaskRepository.list[position])
}
override fun getItemCount(): Int {
return TaskRepository.list.size
}
class TaskViewHolder(private val binding: CardLayoutBinding) : RecyclerView.ViewHolder(binding.root){
var bCopyText: Button? = null
fun bind(task: TaskResponse) {
binding.idActivityName.text = task.title
binding.idActivityDescription.text = task.description
bCopyText = findViewById<View>(R.id.copyactivity) as Button
val clipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
bCopyText!!.setOnClickListener {
val clipData = ClipData.newPlainText("", task.description,)
clipboardManager.setPrimaryClip(clipData)
Toast.makeText(RecyclerView, "message...", Toast.LENGTH_SHORT).show()
}
}
private fun getSystemService(clipboardService: String): Any {
}
}
}
There are two lines in my code that are throwing up problems:
bCopyText = findViewById<View>(R.id.copyactivity) as Button
and
Toast.makeText(RecyclerView, "message...", Toast.LENGTH_SHORT).show()
I've tried different variances of the two above lines and research many articles on StackOverflow but with no winner, can anyone help?
Managed to get this working utilising help from Gobu:
class TaskViewHolder(private val binding: CardLayoutBinding) : RecyclerView.ViewHolder(binding.root){
fun bind(task: TaskResponse) {
binding.idActivityName.text = task.title
binding.idActivityDescription.text = task.description
binding.copyactivity
binding.copyactivity.setOnClickListener {
val clipboardManager = itemView.context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("", task.title +"\n\n" + task.description)
clipboardManager.setPrimaryClip(clipData)
Toast.makeText(itemView.context, "Activity copied to clipboard", Toast.LENGTH_SHORT).show()
}
}
First of all, if you're using ViewBinding, why would you declare a variable for your button? Just get it from the binding.
Second, it's giving you an error, because you're making sure (!!) that the button you declare isn't null, but most likely it is, because you're trying to get the ID of a view you don't have.
Third, RecyclerView is not a context, if you are using ViewBinding, you get the context from binding.root.context
I have a grid supported by recyclerview inside a ConstraintLayout inside a ScrollView.
Although 20 items are inserted in setList() (I debugged it), only 9 items are displayed when using ScrollView
When I switch to NestedScrollView all 20 items are displayed, but the items in the middle are streched. Not the images, but it seems that there is a background behind streched 3 times the actual size of the item/image.
I'm using androidx libraries.
Fragment layout
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimaryDark"
tools:context=".ui.details.DetailsFragment">
<ImageView
android:id="#+id/detail_backdrop"
android:layout_width="match_parent"
android:layout_height="220dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
android:scaleType="centerCrop"
android:src="#drawable/clapperboard"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/play_symbol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="#+id/detail_backdrop"
app:layout_constraintEnd_toEndOf="#+id/detail_backdrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/detail_backdrop"
app:srcCompat="#drawable/ic_play_circle_outline_white_96dp" />
<ProgressBar
android:id="#+id/details_progress_bar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Some other views...
<TextView
android:id="#+id/tv_my_list_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/my_list_at_details"
app:layout_constraintEnd_toEndOf="#+id/wish_list_btn"
app:layout_constraintStart_toStartOf="#+id/wish_list_btn"
app:layout_constraintTop_toBottomOf="#id/wish_list_btn" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_recommended"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tv_my_list_details"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
List item layout
<androidx.cardview.widget.CardView 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:id="#+id/movie_card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="10dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/movie_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/iv_poster"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="#drawable/clapperboard" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
Adapter
package com.lacourt.myapplication.ui.details
import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Point
import android.graphics.drawable.Drawable
import android.util.DisplayMetrics
import android.util.Log
import android.view.Display
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.lacourt.myapplication.AppConstants
import com.lacourt.myapplication.R
import com.lacourt.myapplication.dto.DbMovieDTO
import com.lacourt.myapplication.ui.OnItemClick
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.movie_list_item.view.*
class RecommendedAdapter(
private val context: Context?,
private val onItemClick: OnItemClick,
private var list: ArrayList<DbMovieDTO>
) : RecyclerView.Adapter<RecommendedHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecommendedHolder {
val view =
LayoutInflater.from(context).inflate(R.layout.list_item_recommended, parent, false)
return RecommendedHolder(view)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: RecommendedHolder, position: Int) {
Log.d("grid-log", "onBindViewHolder() called, position = $position, list.size = ${list.size}")
// get device dimensions
val displayMetrics = DisplayMetrics()
(context as Activity).windowManager.defaultDisplay.getMetrics(displayMetrics)
val width = displayMetrics.widthPixels
val maxHeight= width.div(3) * 1.5
holder.poster.minimumHeight = maxHeight.toInt()
holder.apply {
Picasso.get()
.load("${AppConstants.TMDB_IMAGE_BASE_URL_W185}${list[position].poster_path}")
.placeholder(R.drawable.clapperboard)
.into(poster)
cardView.setOnClickListener {
val id = list[position].id
if (id != null)
onItemClick.onItemClick(id)
else
Toast.makeText(
context,
"Sorry. Can not load this movie. :/",
Toast.LENGTH_SHORT
).show()
}
}
}
fun setList(list: List<DbMovieDTO>) {
Log.d("grid-log", "setList() called")
this.list.clear()
this.list.addAll(list)
notifyDataSetChanged()
}
}
class RecommendedHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var poster = itemView.iv_poster
var cardView = itemView.movie_card_view
}
Any solutions for this strange behavior?
Since it may help someone in the future, I found a solution:
I just added holder.cardView.layoutParams.height = maxHeight.toInt() to onBindViewHolder of my adapter class and now every item layout is in the correct size.
Since you are using a constraint layout, you should let the constraints set the size, in general.
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_recommended"
android:layout_width="0dp"
android:layout_height="dp"
...
0dp in this case means let the constraints set the value.
I am new to kotlin. Here I am implementing login screen to my application, and the implementation of class using kotlin as below with xml file, but when I am clicking on button or textview onclick is not responding. please help me to resolve this.
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.*
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import butterknife.BindView
import butterknife.ButterKnife
import butterknife.OnClick
class login : AppCompatActivity(), View.OnClickListener {
#BindView(R.id.title) var title: TextView? = null
#BindView (R.id.email) var email : TextView? = null
#BindView (R.id.password) var pass : TextView? = null
#BindView (R.id.tv_fp) var fp : TextView? = null
#BindView (R.id.tv_register) var register : TextView? = null
#BindView (R.id.btn_login ) var login : Button? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
ButterKnife.bind(this)
// change to register!!.setOnClickListener(this) to make sure your view is injected
register?.setOnClickListener(this)
login?.setOnClickListener(this)
}
// v--- change the parameter type View? to View, it is never be null
override fun onClick(p0: View?) {
// v--- remove it
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
// v--- remove the redundant safe-call ?.
if(p0?.id == R.id.tv_register){
Log.e("login", "i")
var intent = Intent(this#login, signin:: class.java)
startActivity(intent)
}
if(p0?.id == R.id.btn_login){
Toast.makeText(this, "Login Button clicked", Toast.LENGTH_SHORT)
}
}
}
and layout file of this class is as below, i used constrainedLayout
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_margin="20dp">
<android.support.design.widget.TextInputEditText
android:id="#+id/email"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Email id"
android:textCursorDrawable="#drawable/cursor_color"
android:backgroundTint="#color/skyBlue"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="100dp"
app:layout_constraintHorizontal_bias="0.0"
android:inputType="textEmailAddress"/>
<android.support.design.widget.TextInputEditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Password"
android:textCursorDrawable="#drawable/cursor_color"
android:id="#+id/password"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="#+id/email"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
android:inputType="textPassword"/>
<Button
android:id="#+id/btn_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="36dp"
android:background="#color/yellow"
android:textStyle="bold"
app:layout_constraintTop_toBottomOf="#+id/password"
android:layout_marginStart="4dp" />
<TextView
android:id="#+id/tv_fp"
android:layout_width="171dp"
android:layout_height="22dp"
android:text="FORGOT PASSWORD?"
android:background="?attr/selectableItemBackground"
tools:layout_editor_absoluteY="301dp"
android:layout_marginStart="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/tv_register"
android:layout_marginTop="6dp"
android:layout_marginBottom="7dp"
app:layout_constraintBottom_toTopOf="#+id/btn_login" />
<TextView
android:id="#+id/tv_register"
android:layout_width="156dp"
android:layout_height="18dp"
android:layout_marginStart="8dp"
android:text="Register"
android:background="?attr/selectableItemBackground"
android:gravity="right"
app:layout_constraintStart_toEndOf="#+id/tv_fp"
app:layout_constraintTop_toTopOf="#+id/button"
android:layout_marginTop="58dp"
app:layout_constraintBottom_toBottomOf="#+id/btn_login"
/>
</android.support.constraint.ConstraintLayout>