I have a LoginActivity in which there are two fragments. Using the navigation library, I switch between these fragments. But now I need to go from the fragment to another Activity. My code doesn't work for some reason, there are no errors in logCat. When I used this code with Activity everything works well. Is it all about a fragment or the navigation library?
My ViewModel
class AuthViewModel #Inject constructor(private var mAuth: FirebaseAuth) : ViewModel() {
var mEmail: String = ""
var mPassword: String = ""
var loginListener: LoginListener? = null
fun login(view: View) {
if (mEmail.isNotEmpty() && mPassword.isNotEmpty()) {
mAuth = FirebaseAuth.getInstance()
mAuth.signInWithEmailAndPassword(mEmail, mPassword).addOnCompleteListener {
if (it.isSuccessful) {
loginListener?.startLoading()
android.os.Handler().postDelayed({
loginListener?.endLoading()
loginListener?.validateLoginAndPassword()
}, 500)
} else {
loginListener?.showError(textResource = R.string.login_error)
}
}
} else {
loginListener?.showError(textResource = R.string.login_or_password_empty)
}
}
}
My Fragment
class LoginFragment : DaggerFragment(), View.OnClickListener, KeyboardVisibilityEventListener, LoginListener {
private lateinit var navController: NavController
lateinit var binding: FragmentLoginBinding
#Inject
lateinit var factory: ViewModelProvider.Factory
lateinit var mAuthViewModel: AuthViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
binding = FragmentLoginBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
navController = Navigation.findNavController(view)
view.btn_registration.setOnClickListener(this)
mAuthViewModel = ViewModelProviders.of(this#LoginFragment, factory).get(AuthViewModel::class.java)
}
override fun onClick(view: View?) {
when(view!!.id) {
R.id.btn_registration -> navController.navigate(R.id.action_loginFragment_to_registerFragment)
}
}
override fun validateLoginAndPassword() {
//startActivity(Intent(activity, ContactListActivity::class.java))
val intent = Intent(activity, ContactListActivity::class.java)
startActivity(intent)
}
My LoginFragment XML
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="loginViewModel"
type="com.infernal93.phonebookappmvvmanddagger.viewmodels.AuthViewModel" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
tools:context=".view.fragments.LoginFragment">
<ScrollView
android:id="#+id/root_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true" >
<EditText
android:id="#+id/login_email"
android:layout_width="300dp"
android:layout_height="50dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="200dp"
android:background="#drawable/bg_inputs"
android:ems="10"
android:hint="#string/email_text"
android:text="#={loginViewModel.mEmail}"
android:inputType="textEmailAddress"
android:textColorHint="#color/dark_gray" />
<EditText
android:id="#+id/login_password"
android:layout_width="300dp"
android:layout_height="50dp"
android:layout_below="#id/login_email"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:background="#drawable/bg_inputs"
android:hint="#string/password_text"
android:text="#={loginViewModel.mPassword}"
android:inputType="textPassword"
android:textColorHint="#color/dark_gray" />
<com.github.rahatarmanahmed.cpv.CircularProgressView
android:id="#+id/cpv_login"
android:layout_width="#dimen/cpv_size"
android:layout_height="#dimen/cpv_size"
android:layout_below="#id/login_password"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:visibility="gone"
app:cpv_animAutostart="true"
app:cpv_color="#color/colorPrimary"
app:cpv_indeterminate="true" />
<Button
android:id="#+id/btn_login_enter"
android:layout_width="250dp"
android:layout_height="50dp"
android:layout_below="#id/cpv_login"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:background="#drawable/bg_buttons"
android:text="#string/login_btn_text"
android:textAllCaps="false"
android:textColor="#color/white"
android:textSize="#dimen/login_btns_text_size"
android:onClick="#{(view) -> loginViewModel.login(view)}"/>
<Button
android:id="#+id/btn_registration"
android:layout_width="250dp"
android:layout_height="50dp"
android:layout_below="#id/btn_login_enter"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:background="#drawable/bg_buttons"
android:text="#string/registration_btn_text"
android:textAllCaps="false"
android:textColor="#color/white"
android:textSize="#dimen/login_btns_text_size" />
</RelativeLayout>
</ScrollView>
</FrameLayout>
</layout>
You didn't bind ViewModel with View. Use below:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
navController = Navigation.findNavController(view)
view.btn_registration.setOnClickListener(this)
mAuthViewModel = ViewModelProviders.of(this#LoginFragment, factory).get(AuthViewModel::class.java)
//Bind viewmodel
binding.loginViewModel = mAuthViewModel
}
I forgot to specify LoginListener in the fragment
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
//return inflater.inflate(R.layout.fragment_login, container, false)
binding = FragmentLoginBinding.inflate(inflater, container, false)
mAuthViewModel = ViewModelProviders.of(this#LoginFragment, factory).get(AuthViewModel::class.java)
binding.loginViewModel = mAuthViewModel
// LoginListener
mAuthViewModel.loginListener = this
return binding.root
}
Related
The problem here is when I'm returning from my support fragment to home fragment back every time my items in the recycle viewer got doubled. Each time i am shifting fragment to fragment my recycle viewer item in the homefragment got doubled. But when, I reopen the app its all got corrected but when i click on another fragment and come back the item in recycle viewer in home fragment got doubled. Kindly help me
// **HomeFragment.kt**
package com.service.bookitapp
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.fragment_home.*
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
class HomeFragment : Fragment() {
private var param1: String? = null
private var param2: String? = null
private val arrCategory = ArrayList<CategoryModel>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_home, container, false)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val recyclerView =view.findViewById<RecyclerView>(R.id.recyclerCategory)
arrCategory.add(CategoryModel(R.drawable.electrician,"Electrician"))
arrCategory.add(CategoryModel(R.drawable.plumber,"Plumber"))
arrCategory.add(CategoryModel(R.drawable.acservice,"AC Service"))
arrCategory.add(CategoryModel(R.drawable.carpentry,"Carpentry"))
arrCategory.add(CategoryModel(R.drawable.drop,"Pick up & Drop"))
arrCategory.add(CategoryModel(R.drawable.painting,"Painting"))
arrCategory.add(CategoryModel(R.drawable.waterfilter,"Water Filter Repair"))
arrCategory.add(CategoryModel(R.drawable.packer,"Pack and Move"))
recyclerView.layoutManager = GridLayoutManager(context,3)
val recyclerAdapter = context?.let { RecycleCategoryAdapter(it,arrCategory) }
recyclerView.adapter = recyclerAdapter
}
}
// **fragment_home.xml**
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FAF9F6"
android:padding="5dp"
android:orientation="vertical"
tools:context=".HomeFragment">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="UselessParent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/welcome_user"
android:textColor="#color/teal_200"
android:textSize="28sp"
android:padding="8dp"
android:textStyle="bold"
tools:ignore="RelativeOverlap" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_alignParentEnd="true"
android:src="#drawable/profile"
android:padding="4dp"
android:contentDescription="#string/app_name" />
</RelativeLayout>
<RelativeLayout
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/catg"
android:textStyle="bold"
android:textColor="#6E16e8"
android:layout_alignParentStart="true"
android:textSize="22sp"/>
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="370dp"
android:id="#+id/recyclerCategory">
</androidx.recyclerview.widget.RecyclerView>
<LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/offers"
android:textStyle="bold"
android:layout_marginBottom="5dp"
android:textColor="#6E16e8"
android:textSize="22sp"/>
<HorizontalScrollView
android:layout_margin="8dp"
android:layout_width="350dp"
android:layout_height="200dp"
tools:ignore="UselessParent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="350dp"
android:layout_height="wrap_content"
android:src="#drawable/plumbingservice"
android:contentDescription="#string/elect" />
<ImageView
android:layout_width="350dp"
android:layout_height="wrap_content"
android:contentDescription="#string/elect"
android:src="#drawable/cleanview" />
<ImageView
android:layout_width="360dp"
android:layout_height="wrap_content"
android:contentDescription="#string/elect"
android:src="#drawable/elecview" />
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</LinearLayout>
The followig are the images
first solution, before add first item in list, call clear
arrCategory.clear()
second solution, populate your list in onCreate method of your fragment
Have you tried moving this
private val arrCategory = ArrayList<CategoryModel>(),
locally inside onViewCreated() ?
like this
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val recyclerView =view.findViewById<RecyclerView>(R.id.recyclerCategory)
val arrCategory = ArrayList<CategoryModel>() // <-- like this?
arrCategory.add(CategoryModel(R.drawable.electrician,"Electrician")
...
...
...
or you can simply initialize the list like this, removing all of it out of the onCreate()
private val arrCategory = arrayListOf<CategoryModel>(
CategoryModel(R.drawable.electrician,"Electrician"),
CategoryModel(R.drawable.plumber,"Plumber"),
CategoryModel(R.drawable.acservice,"AC Service"),
CategoryModel(R.drawable.carpentry,"Carpentry"),
CategoryModel(R.drawable.drop,"Pick up & Drop"),
CategoryModel(R.drawable.painting,"Painting"),
CategoryModel(R.drawable.waterfilter,"Water Filter Repair"),
CategoryModel(R.drawable.packer,"Pack and Move")
)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val recyclerView =view.findViewById<RecyclerView>(R.id.recyclerCategory)
recyclerView.layoutManager = GridLayoutManager(context,3)
val recyclerAdapter = context?.let { RecycleCategoryAdapter(it,arrCategory) }
recyclerView.adapter = recyclerAdapter
}
I don't know how to add DataStore in setting fragment, where the user can change the "value" of the key of the API . This is thehttps://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&orderby=time&minmag=5&limit=10 API im using . From the API i want to change the minmag value where the user can put any value of minmag in setting fragment the result should be saved in shared preference and also the result should be display in the main activity
Im using kotlin, retrofit and following android architecture component
EarthquakeApiService.kt
private const val BASE_URL = "https://earthquake.usgs.gov/fdsnws/"
// https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&orderby=time&minmag=5&limit=10
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(BASE_URL)
.build()
interface EarthquakeApiService {
#GET("event/1/query?")
suspend fun getJson (#Query("minmag") minMagnitude : String,
#Query("format") formatted : String, #Query("limit") limited: String,
#Query("orderby") orderBy : String) : EarthquakeResponse
}
object BookApi {
val retrofitService : EarthquakeApiService by lazy { retrofit.create(EarthquakeApiService::class.java) }
}
EarthquakeResponse.kt
data class EarthquakeResponse( val features : Array<Feature> ?)
data class Feature( val properties : Properties)
data class Properties(val mag : Double,
val place : String , val time : Long)
OverviewFragment
class OverviewFragment : Fragment() {
private val viewModel: OverviewViewModel by lazy {
ViewModelProvider(this).get(OverviewViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val binding: FragmentOverviewBinding = DataBindingUtil.inflate(
inflater, R.layout.fragment_overview, container, false)
binding.viewModel = viewModel
binding.recycleList.adapter = RecyclerviewAdapter()
binding.lifecycleOwner = this
setHasOptionsMenu(true)
binding.button.setOnClickListener { view: View ->
view.findNavController().navigate(R.id.action_overviewFragment_to_settingsFragment)
}
return binding.root
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater?.inflate(R.menu.overflow_menu, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return NavigationUI.onNavDestinationSelected(item, requireView().findNavController())
|| super.onOptionsItemSelected(item)
}
}
OverviewViewModel
class OverviewViewModel : ViewModel() {
lateinit var minMagnitude : String
lateinit var orderBy: String
// Internally, we use a MutableLiveData, because we will be updating the List of MarsProperty
// with new values
private val _properties = MutableLiveData<EarthquakeResponse> ()
// The external LiveData interface to the property is immutable, so only this class can modify
val properties: LiveData<EarthquakeResponse>
get() = _properties
init {
getBookProperties()
}
private fun getBookProperties() {
viewModelScope.launch {
try {
_properties.value = BookApi.retrofitService.getJson("2",
"geojson", "10", "time")
} catch (e : Exception) {
}
}
}
}
RecyclerviewAdapter.kt
class RecyclerviewAdapter() : ListAdapter<Feature, RecyclerviewAdapter.EarthquakePropertyViewHolder>(DiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EarthquakePropertyViewHolder {
return EarthquakePropertyViewHolder.from(parent)
}
override fun onBindViewHolder(holder: EarthquakePropertyViewHolder, position: Int) {
val item = getItem(position)
holder.bind(item)
}
class EarthquakePropertyViewHolder private constructor(val binding: EarthquakeRawBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(books: Feature) {
binding.property = books
binding.executePendingBindings()
}
companion object {
fun from(parent: ViewGroup): EarthquakePropertyViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view = EarthquakeRawBinding.inflate(layoutInflater, parent, false)
return EarthquakePropertyViewHolder(view)
}
}
}
}
class DiffCallback : DiffUtil.ItemCallback<Feature>() {
override fun areItemsTheSame(oldItem: Feature, newItem: Feature): Boolean {
return oldItem === newItem
}
override fun areContentsTheSame(oldItem: Feature, newItem: Feature): Boolean {
return oldItem == newItem
}
}
BindingAdapter.kt
#BindingAdapter("listData")
fun bindRecyclerView(recyclerView: RecyclerView, data: EarthquakeResponse?) {
val adapter = recyclerView.adapter as RecyclerviewAdapter
if (data != null) {
adapter.submitList(data.features?.toList())
}
}
#BindingAdapter("magnitude")
fun bindAuthor(textView: TextView, magName : Double) {
val decimalFormat = DecimalFormat("0.0")
val formattedMagnitude = decimalFormat.format(magName)
textView.setText(formattedMagnitude.toString())
}
#BindingAdapter("place")
fun bindTitle(textView: TextView, titlePlace : String) {
textView.setText(titlePlace)
}
#BindingAdapter("time")
fun bindTime(textView: TextView, titleTime :Long) {
val timeFormat = SimpleDateFormat("h:mm a")
val formattedTime = timeFormat.format(titleTime)
textView.setText(formattedTime.toString())
}
#BindingAdapter("date")
fun bindDate(textView: TextView, titleTime :Long) {
val timeFormat = SimpleDateFormat("LLL dd, yyyy")
val formattedDate = timeFormat.format(titleTime)
textView.setText(formattedDate.toString())
}
MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
SettingsFragment
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
}
}
activity_main.xml
RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.kotlinearthquake.MainActivity"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<fragment
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/myNavHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph"
tools:ignore="MissingClass" />
</RelativeLayout>
earthquake_raw.xml
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<data>
<variable
name="property"
type="com.example.kotlinearthquake.network.Feature" />
</data>
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="150dp"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingLeft="16dp"
android:paddingEnd="16dp"
android:paddingRight="16dp">
<TextView
android:id="#+id/magnitude"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="center_vertical"
android:background="#drawable/magnitude_circle"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:textColor="#android:color/black"
android:textSize="16sp"
app:magnitude="#{property.properties.mag}"
tools:text="8.9" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="#+id/location_offset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="sans-serif-medium"
android:maxLines="1"
android:textAllCaps="true"
android:textColor="#android:color/black"
android:textSize="12sp"
tools:text="30km S of\n" />
<TextView
android:id="#+id/primary_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#android:color/black"
android:textSize="12sp"
app:place="#{property.properties.place}"
tools:text="Long placeholder that should wrap to more than 2 line of text" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:orientation="vertical">
<TextView
android:id="#+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:textColor="#color/textColorEarthquakeDetails"
android:textSize="12sp"
app:date="#{property.properties.time}"
tools:text="Mar 6, 2010" />
<TextView
android:id="#+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:textColor="#color/textColorEarthquakeDetails"
android:textSize="12sp"
app:time="#{property.properties.time}"
tools:text="3:00 PM" />
</LinearLayout>
</LinearLayout>
</layout>
fragment_overview.xml
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.example.kotlinearthquake.overview.OverviewViewModel" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context = "com.example.kotlinearthquake.MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycle_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:listData="#{viewModel.properties}"
tools:listitem="#layout/earthquake_raw"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
<TextView
android:id="#+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textAppearance="?android:textAppearanceMedium"/>
<ProgressBar
android:id="#+id/loading_indicator"
style="#style/Widget.AppCompat.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="40dp"
android:layout_marginBottom="53dp"
android:text="Setting" />
</RelativeLayout>
</layout>
root_preferences.xml
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:defaultValue="#string/settings_order_by_default"
android:entries="#array/settings_order_by_label"
android:entryValues="#array/settings_order_by_value"
android:key="#string/settings_order_by_key"
android:title="#string/settings_order_by_label"/>
<EditTextPreference
android:defaultValue="#string/settings_min_magnitude_default"
android:inputType="numberDecimal"
android:key="#string/settings_min_magnitude_key"
android:selectAllOnFocus="true"
android:title="#string/settings_min_magnitude_label" />
</PreferenceScreen>
I tried but didn't found any good answer for my problem .. im literally stuck from the last 1 month ,Please help me , I'm still new to android and Kotlin programming.
So I've been searching on internet for a while already now but I just can't seem to find the correct topic to help me out with this.
I have the following code which is relevant for this question:
This is my adapter class.
class SmoelenBoekAdapter(var profiles: Array<Profile>) : RecyclerView.Adapter<CustomViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val layout = layoutInflater.inflate(com.otten.nvvofrankversie.R.layout.recyclerview_smoelenboek, parent, false)
return CustomViewHolder(layout)
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val positioner = profiles.get(position)
var profileImage = positioner.profile_image
var firstName = positioner.first_name
var lastName = positioner.last_name
var plaats = positioner.place
var adres = positioner.address
holder.view.naamSmoelenBoek.text = firstName.string + " " + lastName.string
}
override fun getItemCount(): Int {
return profiles.size
}
}
class CustomViewHolder(val view: View) : RecyclerView.ViewHolder(view)
This is my 'MainActivity' (for this particular fragment)
class SmoelenBoek : ApplicationFragment(){
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_smoelenboek, null)
}
/*override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
smoelenboekRecyclerView.adapter = SmoelenBoekAdapter(profiles)
}*/
}
xml where adapterinfo has to be filled in:
<?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"
android:orientation="vertical">
<ImageView
android:id="#+id/profielPicSmoelenBoek"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/business_icon" />
<TextView
android:id="#+id/naamSmoelenBoek"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="Frank Otten"
android:textColor="#color/colorPrimaryDark"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="#+id/profielPicSmoelenBoek"
app:layout_constraintStart_toEndOf="#+id/profielPicSmoelenBoek"
app:layout_constraintTop_toBottomOf="#+id/profielPicSmoelenBoek" />
<TextView
android:id="#+id/textView17"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:text=">"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#+id/naamSmoelenBoek" />
</androidx.constraintlayout.widget.ConstraintLayout>
And this is the fragment where I have a recyclerview in which needs to be filled with the above 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:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView8"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/offer_bg"
android:adjustViewBounds="true"
android:scaleType="center"/>
<Button
android:id="#+id/searchInSmoelenBoek"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="60dp"
android:layout_marginEnd="15dp"
android:background="#color/lightGray"
android:hint="Zoek in smoelenboek"
android:padding="10dp"
android:textAlignment="textStart"
android:textColor="#color/colorAccent"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="60dp"
android:text="Vind gemakkelijk alle\naangesloten orthodontisten"
android:textColor="#color/white"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/searchInSmoelenBoek" />
<TextView
android:id="#+id/textView15"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:text="Aangesloten orthodontisten"
android:textAlignment="textStart"
android:textColor="#color/browser_actions_title_color"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageView8" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/smoelenboekRecyclerView"
android:layout_width="409dp"
android:layout_height="440dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView15"/>
</androidx.constraintlayout.widget.ConstraintLayout>
What am I doing wrong or missing here?
I think I still need to set the adapter correctly, but I can't figure that out either...
Hope anyone can help me!
// Set layout manager for recycler view
smoelenboekRecyclerView.layoutManager = LinearLayoutManager(this);
// Set adapter to recycler view
smoelenboekRecyclerView.adapter = SmoelenBoekAdapter(profiles)
class CustomViewHolder(val view: View) : RecyclerView.ViewHolder(view){
val tvNaamSmolText = view.naamSmoelenBoek
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val positioner = profiles.get(position)
var profileImage = positioner.profile_image
var firstName = positioner.first_name
var lastName = positioner.last_name
var plaats = positioner.place
var adres = positioner.address
holder.tvNaamSmolText.text = firstName.string + " " + lastName.string
}
Try this
class SmoelenBoek : ApplicationFragment(){
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
View view = inflater.inflate(R.layout.fragment_smoelenboek, null)
view.smoelenboekRecyclerView.layoutManager = LinearLayoutManager(this);
view.smoelenboekRecyclerView.adapter = SmoelenBoekAdapter(profiles)
return view
}
}
}
class SmoelenBoek : ApplicationFragment(){
var profiles: Array<Profile> = arrayOf()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_smoelenboek, null)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
SharedInstance.api.getAllUsers {
profiles = it
smoelenboekRecyclerView.layoutManager = LinearLayoutManager(context)
smoelenboekRecyclerView.adapter = SmoelenBoekAdapter(profiles)
}
}
}
This is the solution to my problem.
I had to put the layoutmanager and adapter in OnviewCreated AFTER the async call (which I forgot to implement so that was part of the problem first) so the layoutmanager could be set and the adapter could fill my recyclerview with items.
Thanks for the help anyways guys!
i create custom attribute use by BindingAdapter,but it unable to use in layout
BindingAdapter
#BindingAdapter("android:killAble")
fun View.setKillAble(killAble: Boolean) {
this.isEnabled = killAble
}
layout
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:id="#+id/et_height"
android:killAble="true"
android:layout_marginTop="32dp"
app:layout_constraintTop_toBottomOf="#+id/et_name"
android:layout_marginStart="16dp"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginRight="16dp"
/>
HomeFragment.kt
class HomeFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val binding: FragmentHomeBinding = DataBindingUtil.inflate(inflater,
R.layout.fragment_home, container, false)
val rootView = binding.root
val viewmodel=ViewModelProviders.of(this).get(HomeViewModel::class.java)
binding.lifecycleOwner = this
binding.viewModel = viewmodel
return rootView
}
}
please help me
You must use the data binding syntax:
android:killAble="#{true}"
I have two Fragments hosted in one Activity. They are dead simple:
class OneFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.fragment_one, container, false)
val sharedView = view.findViewById<View>(R.id.shared_view)
ViewCompat.setTransitionName(sharedView, "test")
view.findViewById<Button>(R.id.go_button).setOnClickListener {
val fragmentTransaction = fragmentManager.beginTransaction()
val oneFragment = fragmentManager.findFragmentById(R.id.fragment_container_frame_layout)
val twoFragment = TwoFragment()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val moveTransition = TransitionInflater.from(activity).inflateTransition(android.R.transition.move)
oneFragment.exitTransition = Fade()
val transitionSet = TransitionSet()
transitionSet.addTransition(TransitionInflater.from(activity).inflateTransition(android.R.transition.move))
transitionSet.duration = 600
twoFragment.sharedElementEnterTransition = transitionSet
twoFragment.enterTransition = Fade()
fragmentTransaction.addToBackStack(TwoFragment::class.java.simpleName)
fragmentTransaction.addSharedElement(sharedView, "test")
fragmentTransaction.replace(R.id.fragment_container_frame_layout, twoFragment)
fragmentTransaction.commit()
}
else {
fragmentTransaction.addToBackStack(TwoFragment::class.java.simpleName)
fragmentTransaction.replace(R.id.fragment_container_frame_layout, twoFragment)
fragmentTransaction.commit()
}
}
return view
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.kravtsov.transitiontest.MainActivity">
<View
android:id="#+id/shared_view"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerInParent="true"
android:background="#android:color/holo_blue_dark" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/shared_view"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:text="HELLO"
tools:ignore="HardcodedText" />
<Button
android:id="#+id/go_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="GO"
tools:ignore="HardcodedText" />
</RelativeLayout>
And the second one:
class TwoFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.fragment_two, container, false)
val sharedView = view.findViewById<View>(R.id.shared_view)
ViewCompat.setTransitionName(sharedView, "test")
return view
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.kravtsov.transitiontest.MainActivity">
<View
android:id="#+id/shared_view"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_below="#+id/anchor"
android:layout_centerHorizontal="true"
android:background="#android:color/holo_blue_dark" />
<TextView
android:id="#+id/anchor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:text="WORLD"
tools:ignore="HardcodedText" />
</RelativeLayout>
As you can see they have common shared view, that i want to animate during transition. The problem is - animation never appears. I can see that enter and exit fade transition for the rest of elements working correctly. Only shared element transition do not work.
I've searched web a lot and mimic a lot of guiedes... No answers i found still. Does anyone face such an issue? Where shoud i start to fix this bug?
Your code is working for me. I've used your layout and kotlin code, and it works seamlessly. One thing I took care of is importing all classes of support packages.