Row item width changes on scrolling in recyclerview in Android - java

The RecyclerView calling inside Alert Dialog, I have tried setting width MATCH_PARENT at run time in onCreateView in adapter class.
if (binding.root.getLayoutParams ().width == RecyclerView.LayoutParams.MATCH_PARENT)
binding.root.getLayoutParams ().width = parent.getWidth ()
Tried calling inside in onCreateView but leaving space vertically. I tried all possible combination which is present on SO but nothing is working.
private fun initDialog() {
if (mAlertDialog == null) {
val mBuilder = AlertDialog.Builder(this)
val view1 = layoutInflater.inflate(R.layout.select_itinerary_dialog, null, false)
val mRecyclerView = view1.findViewById<RecyclerView>(R.id.mRecyclerView)
mRecyclerView?.adapter = SelectItineraryAdapter(this#AddItineraryActivity)
val llm = LinearLayoutManager(this#AddItineraryActivity)
// llm.isAutoMeasureEnabled = false
mRecyclerView?.layoutManager = llm
//mRecyclerView?.layoutManager = LinearLayoutManager(this#AddItineraryActivity)
mCheckBoxSelectAll = view1.findViewById<CheckBox>(R.id.checkSelctAll)
mCheckBoxSelectAll?.setOnCheckedChangeListener { _, b ->
if (!fromBroadcastReceiver) {
for (item in mItinerarylistResponse?.data?.itinerary!!) {
item?.isSelected = b
}
mRecyclerView?.adapter!!.notifyDataSetChanged()
}
fromBroadcastReceiver = false
}
view1.findViewById<AppCompatButton>(R.id.clearItinerary).setOnClickListener {
mAlertDialog!!.dismiss()
}
view1.findViewById<AppCompatButton>(R.id.doneItinerary).setOnClickListener {
try {
for (item in mItinerarylistResponse?.data?.itinerary!!) {
viewContainer.visibility = View.VISIBLE
if (item!!.item == "Wake Up") {
if (item.isSelected) {
wakeUpTimeTV.visibility = View.VISIBLE
wakeUpTimeLay.visibility = View.VISIBLE
} else {
wakeUpTimeTV.visibility = View.GONE
wakeUpTimeLay.visibility = View.GONE }
}
}
} catch (e: Exception) {
}
mAlertDialog!!.dismiss()
}
mBuilder.setView(view1)
mAlertDialog = mBuilder.create()
mAlertDialog?.window?.setBackgroundDrawableResource(android.R.color.transparent)
// mAlertDialog?.setView(view1)
}
}
Adapter
class SelectItineraryAdapter(val contecx: AddItineraryActivity) : RecyclerView.Adapter<SelectItineraryAdapter.MyHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
val binding = DataBindingUtil.inflate<RowItemItinararyBinding>(LayoutInflater.from(contecx), R.layout.row_item_itinarary, parent, false)
// val v= LayoutInflater.from(contecx).inflate(LayoutInflater.from(contecx), R.layout.row_item_itinarary, parent, false)
/* if (binding.root.getLayoutParams ().width == RecyclerView.LayoutParams.MATCH_PARENT)
binding.root.getLayoutParams ().width = parent.getWidth ()*/
val dd = MyHolder(binding)
return dd
}
override fun getItemCount(): Int {
return mItinerarylistResponse?.data?.itinerary!!.size
}
#SuppressLint("ClickableViewAccessibility")
override fun onBindViewHolder(holder: MyHolder, position: Int) {
holder.v.itinararyname.text = mItinerarylistResponse?.data?.itinerary!![position]?.item
holder.v.markReadCheck.setOnCheckedChangeListener { _, isChecked ->
mItinerarylistResponse?.data?.itinerary!![position]!!.isSelected = isChecked
val receiverIntentDetail = Intent()
receiverIntentDetail.action = isitinerarySelected
holder.v.markReadCheck.context.sendBroadcast(receiverIntentDetail)
}
holder.v.detailLat.setOnTouchListener { view, motionEvent ->
when (motionEvent.action) {
MotionEvent.ACTION_DOWN -> {
com.socrpro.utils.error("ACTION_DOWN")
}
MotionEvent.ACTION_UP -> {
// if (itinerary[position].readStatus == 0) {
holder.v.markReadCheck.performClick()
// }
com.socrpro.utils.error("ACTION_UP")
}
MotionEvent.ACTION_MOVE -> {
com.socrpro.utils.error("ACTION_MOVE")
}
}
true
}
holder.v.markReadCheck.isChecked = mItinerarylistResponse?.data?.itinerary!![position]!!.isSelected
}
class MyHolder(val v: RowItemItinararyBinding) : RecyclerView.ViewHolder(v.root)
}
Row_item
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:id="#+id/detailLat" android:layout_width="match_parent" android:layout_height="wrap_content"
android:clickable="true" android:orientation="vertical">
<LinearLayout android:id="#+id/readornot" android:layout_width="match_parent"
android:layout_height="#dimen/_25sdp" android:background="#color/white"
android:gravity="center_vertical" android:orientation="horizontal"
android:paddingTop="#dimen/_5sdp" android:paddingBottom="#dimen/_5sdp">
<CheckBox android:id="#+id/markReadCheck" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:button="#drawable/custom_checkbox" android:layoutDirection="rtl"
android:text="" />
<TextView android:id="#+id/itinararyname" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_gravity="center_vertical"
android:layout_marginStart="#dimen/_2sdp" android:layout_marginEnd="#dimen/_5sdp"
android:layout_weight="1" android:singleLine="true"
android:text="dfgdgfdggfdg" android:textColor="#color/colorPrimary"
android:textSize="#dimen/_10sdp" />
</LinearLayout>
<View android:layout_width="match_parent" android:layout_height=".5dp"
android:layout_alignBottom="#+id/readornot" android:background="#color/linecolorcc" />
</RelativeLayout>
</layout>

Updated.. new option added..*
TL;DR
Replace your vertical LinearLayout (which surrounds the RecyclerView) with a RelativeLayout
Option1 (old answer)
Before surrounding the layout with ScrollView
After adding ScrollView as root
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/search"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/search"
android:orientation="vertical">
<!--Header-->
<LinearLayout
android:id="#+id/static_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/HeaderStyle"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</RelativeLayout>
</ScrollView>
</layout>
The downside of adding ScrollView is that it causes all the surrounded Views to be Scrolled! So try the next option..
Option2 (better one)
Actually, I was not satisfied with Option1 because the header of the table should not disappear when user scrolls down the RecyclerView! So i've tried to replaced the LinearLayout (which surrounds the RecyclerView) with a RelativeLayout and it get the job done..
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/search"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/search">
<!--Header-->
<LinearLayout
android:id="#+id/static_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignStart="#id/rv"
android:layout_alignEnd="#id/rv"
style="#style/HeaderStyle"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/static_header"/>
</RelativeLayout>
</RelativeLayout>
</layout>

Related

How to Add and Remove Animation RecyclerView's items

I'm making a music app. I have a recyclerview and I am playing clicked item's music, at the same time animation works too. Question is whenever user change the recyclerview's item position I need to cancel first animation and start new one for new position. I mean every time will be just 1 animation exist.
My RecyclerViewAdapter
class RecyclerViewAdapter(private val ModelList:List<Musics>,private val listener:
ClickListener) :RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>(){
class ViewHolder(var binding:GridListBinding):RecyclerView.ViewHolder(binding.root) {
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val view = DataBindingUtil.inflate<GridListBinding>(inflater,R.layout.grid_list,parent,false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: RecyclerViewAdapter.ViewHolder, position: Int) {
holder.binding.musics = ModelList[position]
holder.binding.constraint.setOnClickListener{
listener.buttonClicked(holder.binding.constraint,ModelList[position],position)
}
}
override fun getItemCount(): Int {
return ModelList.size
}
}
My ClickListener for adapter
interface ClickListener {
fun buttonClicked(view: View,model: Musics,position:Int)
}
grid_list for recyclerviewAdapter
<?xml version="1.0" encoding="utf-8"?>
<layout
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"
>
<data>
<variable
name="musics"
type="com.tunahan.musicplayer.model.Musics" />
<variable
name="listener"
type="com.tunahan.musicplayer.adapter.ClickListener" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="125dp"
android:id="#+id/constraint"
android:layout_height="125dp"
android:layout_marginTop="10dp"
android:layout_marginStart="5dp"
tools:layout_editor_absoluteX="52dp"
tools:layout_editor_absoluteY="42dp"
>
<ImageView
android:id="#+id/image"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/linearLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="#drawable/musical"
tools:ignore="ContentDescription"
/>
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="bottom"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:id="#+id/gridTextView"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:fontFamily="#font/allerta"
android:gravity="center"
android:paddingStart="5dp"
android:text="#{musics.filename}"
android:textColor="#color/black"
android:textSize="16sp"
tools:ignore="RtlSymmetry" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
And Pulse Animation for gridlist's imageView
scaleDown = ObjectAnimator.ofPropertyValuesHolder(
view.image,
PropertyValuesHolder.ofFloat("scaleX", 1.1f),
PropertyValuesHolder.ofFloat("scaleY", 1.1f),
)
scaleDown.duration = 500
scaleDown.repeatCount = ObjectAnimator.INFINITE
scaleDown.repeatMode = ObjectAnimator.REVERSE
scaleDown.start()
ClickListener
override fun buttonClicked(view: View, model: Musics, position: Int) {
path = model.filepath
nextMusic = position
positionplus = position
handler.removeCallbacks(runnable)
saveduid = sharedPref.getInt("changed", model.uid)
editor = sharedPref.edit()
editor.putInt("changed", model.uid)
editor.apply()
editor2.putInt("positionplus", positionplus)
editor2.apply()
if (saveduid == model.uid) {
if (mediaPlayer.isPlaying) {
ForegroundService.startService(
this, path = path, action = "ACTION_PAUSE",
positionplus, ModelList[positionplus].filename
)
scaleDown.cancel()
binding.seekbartextend.text = createTimeLabel(mediaPlayer.duration)
binding.playButton.setImageResource(R.drawable.ic_baseline_play_arrow_24)
} else {
ForegroundService.startService(
this, path = path, action = "ACTION_PLAY",
positionplus,ModelList[positionplus].filename
)
binding.seekbartextend.text = createTimeLabel(mediaPlayer.duration)
mediaPlayer.setOnCompletionListener {
nextButton()
}
binding.playButton.setImageResource(R.drawable.circledpause)
runnable = Runnable {
binding.seekBar.max = mediaPlayer.duration
binding.seekBar.progress = mediaPlayer.currentPosition
binding.seekbarTextstart.text = createTimeLabel(mediaPlayer.currentPosition)
binding.seekbartextend.text = createTimeLabel(mediaPlayer.duration)
handler.postDelayed(runnable, 1000)
}
handler.post(runnable)
}
} else {
ForegroundService.startService(
this, path = path, action = "ACTION_RESET",
positionplus,ModelList[positionplus].filename
)
if (positionplus != position)
scaleDown = ObjectAnimator.ofPropertyValuesHolder(
view.image,
PropertyValuesHolder.ofFloat("scaleX", 1.1f),
PropertyValuesHolder.ofFloat("scaleY", 1.1f),
)
scaleDown.duration = 500
scaleDown.repeatCount = ObjectAnimator.INFINITE
scaleDown.repeatMode = ObjectAnimator.REVERSE
scaleDown.start()
binding.seekbartextend.text = createTimeLabel(mediaPlayer.duration)
mediaPlayer.setOnCompletionListener {
nextButton()
}
binding.playButton.setImageResource(R.drawable.circledpause)
runnable = Runnable {
binding.seekBar.max = mediaPlayer.duration
binding.seekBar.progress = mediaPlayer.currentPosition
binding.seekbarTextstart.text = createTimeLabel(mediaPlayer.currentPosition)
binding.seekbartextend.text = createTimeLabel(mediaPlayer.duration)
handler.postDelayed(runnable, 1000)
}
handler.post(runnable)
}
}

How to show Edit text on the bottom in Bottom-Sheet in every state?

I like to integrate comment section in Bottom-sheet. In Comment section i have recyclerView that show all comment and a EditText that situated bottom of the view. when bottom-sheet is open in Collapsed State the Edit text not showing but when State is EXPANDED the the Edit text layout is show. so i need help to show the edit text option in every state.
This is Collapsed state Image
This is Expanded State Image
I want to show Edit text in Collapsed mode just like Expended mood.
XML Layout
<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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".fragment.CommentFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.NestedScrollView
android:id="#+id/nested_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:scrollingCache="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_main"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
<View
android:layout_width="fill_parent"
android:layout_height="?attr/actionBarSize">
</View>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:background="#fff"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true">
<View
android:background="#B1B1B1"
android:layout_width="match_parent"
android:layout_height="1dp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
Code
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
dialog.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE|
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
final View view = View.inflate(getContext(), R.layout.fragment_comment, null);
unbinder = ButterKnife.bind(this, view);
dialog.setContentView(view);
mBehavior = BottomSheetBehavior.from((View) view.getParent());
mBehavior.setPeekHeight(BottomSheetBehavior.PEEK_HEIGHT_AUTO);
mBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
mBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
if (BottomSheetBehavior.STATE_EXPANDED == newState) {
Log.d(TAG, "onStateChanged: STATE_EXPANDED");
}
if (BottomSheetBehavior.STATE_COLLAPSED == newState) {
Log.d(TAG, "onStateChanged: STATE_COLLAPSED");
}
if (BottomSheetBehavior.STATE_HIDDEN == newState) {
Log.d(TAG, "onStateChanged: STATE_HIDDEN");
dismiss();
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
});
commentsAdapterNew = new CommentsAdapterNew(getActivity(), commentsClassList);
RecyclerView.LayoutManager mManager = new LinearLayoutManager(getActivity(), RecyclerView.VERTICAL, true);
rvMain.setLayoutManager(mManager);
rvMain.setAdapter(commentsAdapterNew);
ViewCompat.setNestedScrollingEnabled(rvMain, false);
getAllComment("876");
return dialog;
}

Android kotlin / java - ReclerView strange behavior when hiding parts in holder / xml

I didn't know what proper title for this issue could be.
I'm doing a chat app and this is the part inside the adapter:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val msg = messages[position]
if (msg.who == "you"){
holder.messagemelayout.visibility = View.GONE
holder.messageyou.text = msg.message
}else{
holder.messageyoulayout.visibility = View.GONE
holder.messageme.text = msg.message
}
}
So when the message is sent be me then the layout for "you" (messageyoulayout) get's hidden and vice versa
Not when I add new messages like this:
var count = 1
bbb.setOnClickListener {
messageslist.add(Chat("hey " + count.toString(), "me"))
adapter.notifyItemInserted(adapter.itemCount - 1)
count++
}
The result is this:
And when I don't hide any layouts then the text inside the layout which don't get any update is still getting filled by random old stuff:
I hope the issue is understandable.
How can I fix this? Like completely removing the layout which don't get an update or something.
Thanks in advance
EDIT:
Whole adapter:
class ChatAdapter(val context: Context, private val messages: MutableList<Chat>) : RecyclerView.Adapter<ChatAdapter.ViewHolder>(){
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val msg = messages[position]
if (msg.who == "you"){
holder.messageyou.text = msg.message
holder.messageme.text = ""
holder.messageme.setBackgroundResource(0)
holder.messageyou.setBackgroundResource(R.drawable.round_corners_lightgray_color)
}else{
holder.messageme.text = msg.message
holder.messageyou.text = ""
holder.messageme.setBackgroundResource(R.drawable.round_corners_accent_color)
holder.messageyou.setBackgroundResource(0)
}
}
override fun getItemCount() = messages.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.chat, parent, false)
return ViewHolder(view)
}
class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView!!){
val messageyou = itemView!!.messageyou!!
val messageme = itemView!!.messageme!!
val messageyoulayout = itemView!!.messageyoulayout!!
val messagemelayout = itemView!!.messagemelayout!!
}
}
chat.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/tools"
android:id="#+id/malsehn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="6dp"
app:cardBackgroundColor="#android:color/transparent"
app:cardElevation="0dp">
<LinearLayout
android:id="#+id/messagemelayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="4">
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3">
<TextView
android:id="#+id/messageme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/round_corners_accent_color"
android:paddingLeft="8dp"
android:paddingTop="6dp"
android:paddingRight="8dp"
android:paddingBottom="6dp"
android:text="TextView"
android:textColor="#android:color/white"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/messageyoulayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="4">
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3">
<TextView
android:id="#+id/messageyou"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/round_corners_lightgray_color"
android:paddingLeft="8dp"
android:paddingTop="6dp"
android:paddingRight="8dp"
android:paddingBottom="6dp"
android:text="TextView"
android:textColor="#android:color/black"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
</android.support.constraint.ConstraintLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Don't call it bugged mess when you don't understand how ViewHolder pattern works.
You should have used multiple itemViewTypes instead of flipping views visibility back-to-back (note this entire code goes into your RecyclerView.Adapter):
// constants
companion object {
const val TYPE_YOU = 1
const val TYPE_ME = 2
}
/* This method is called to determine what type of ViewHolder should be used to represent item at [position] */
override fun getItemViewType(position: Int) = if(messages[position].who == "you") TYPE_YOU else TYPE_ME
/* [viewType] determines what ViewHolder we should create. */
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layoutId = when(viewType){
TYPE_YOU -> {
// this viewholder will display only messages from "you", inflate only "you" layout
R.layout.chat_item_you
}
TYPE_ME ->{
// this viewholder will display only messages from "me", inflate only "me" layout
R.layout.chat_item_me
}
else -> throw IllegalArgumentException("Unknown viewType: $viewType")
}
val itemView = LayoutInflater.from(parent.context).inflate(layoutId, parent, false)
return ViewHolder(itemView)
}
// then you can use your original bind method, because "you" and "me" messages will never re-user others ViewHolder
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val msg = messages[position]
if (msg.who == "you"){
// holder.itemViewtype should always be equal to TYPE_YOU here
}else{
// holder.itemViewtype should always be equal to TYPE_ME here
}
holder.message.text = msg.message
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val txtMessage : TextView = itemView.findViewById(R.id.message)
}
Then split chat bubbles into two separate layouts:
chat_item_you.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_margin="6dp"
android:layout_height="wrap_content">
<TextView
android:id="#+id/message"
style="#style/ChatBubbleStyle"
android:background="#drawable/round_corners_lightgray_color"
android:text="TextView"
android:layout_gravity="end" />
</FrameLayout>
And similar but with other color and gravity:
chat_item_me.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_margin="6dp"
android:layout_height="wrap_content">
<TextView
android:id="#+id/message"
style="#style/ChatBubbleStyle"
android:background="#drawable/round_corners_blue_color"
android:text="TextView"
android:layout_gravity="start" />
</FrameLayout>
Use shared style in styles.xml to prevent redundant code:
<style name="ChatBubbleStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:paddingTop">6dp</item>
<item name="android:paddingRight">8dp</item>
<item name="android:paddingBottom">6dp</item>
<item name="android:textColor">#android:color/black</item>
<item name="android:textSize">16sp</item>
</style>
After tryng to set width/height of non used holder to 0, removing background and some other stuff which all "worked" but created other strange behaviors I found the only working non bugged solution:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val msg = messages[position]
if (msg.who == "you"){
holder.messageyou.text = msg.message
holder.messageme.text = ""
holder.messageme.setBackgroundResource(0)
holder.messageyou.setBackgroundResource(R.drawable.round_corners_lightgray_color)
}else{
holder.messageme.text = msg.message
holder.messageyou.text = ""
holder.messageme.setBackgroundResource(R.drawable.round_corners_accent_color)
holder.messageyou.setBackgroundResource(0)
}
}
Yes you have to define the background on BOTH layouts over and over again and tell the holder that there is nothing to fill where it really isn't. Android is a bugged time wasting mess..

Drawer Scrolling Slowly

I have this drawer which opens normally but the scrolling in it is very slow, and I don't know why knowing that the image it has on top of it is not HD image, and available in the 4 sizes, I've done various examples in Java and it was fine, I wonder if the issue is that I'm using Kotlin in the adapter.
I would appreciate any help.
The activity's layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:fitsSystemWindows="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/gradient_background"
android:orientation="vertical">
<include
android:id="#+id/top"
layout="#layout/top_bar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize" />
<TextView
android:layout_below="#+id/top"
android:id="#+id/tvTradesTicker"
android:layout_width="match_parent"
android:layout_height="#dimen/trades_ticker_height"
android:background="#color/colorPrimaryLight"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:focusable="true"
android:freezesText="true"
android:marqueeRepeatLimit="marquee_forever"
android:padding="#dimen/small_margin"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="#color/darkGray"
android:textSize="#dimen/font"
android:visibility="visible" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rvGrid"
android:layout_below="#+id/tvTradesTicker"
android:layout_above="#+id/llFooter"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include
layout="#layout/footer"
android:id="#+id/llFooter"
android:layout_width="match_parent"
android:layout_height="#dimen/footer_height"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/white"
android:fitsSystemWindows="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:paddingTop="#dimen/big_margin_padding"
android:orientation="vertical">
<include
layout="#layout/item_drawer_header"
android:id="#+id/header"
android:background="#color/white"
android:layout_width="match_parent"
android:layout_height="#dimen/drawer_header_height" />
<ListView
android:id="#+id/lvItems"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#color/white"
android:divider="#android:color/transparent"
android:paddingTop="#dimen/small_margin" />
</LinearLayout>
</android.support.design.widget.NavigationView>
The Drawer's Adapter:
class DrawerListAdapter : BaseAdapter {
private var drawerItems: MutableList<DrawerItem> = mutableListOf()
private var context: Context? = null
constructor(context: Context, notesList: MutableList<DrawerItem>) : super() {
this.drawerItems = notesList
this.context = context
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View? {
val view: View?
val vh: ViewHolder
val inflater = LayoutInflater.from(context)
val type = getItemViewType(position)
if (convertView == null) {
view = if (type == 0){
inflater.inflate(R.layout.item_drawer_section, parent, false)
}else{
inflater.inflate(R.layout.item_drawer_child, parent, false)
}
vh = ViewHolder(view)
view.tag = vh
} else {
view = convertView
vh = view.tag as ViewHolder
}
val drawerItem = drawerItems[position]
vh.name.text = drawerItem.name
if (type == 0){
vh.rel.setBackgroundColor(ContextCompat.getColor(context!!, R.color.blue))
vh.name.setBackgroundColor(ContextCompat.getColor(context!!, R.color.colorAccent))
vh.name.setTextColor(ContextCompat.getColor(context!!, R.color.white))
}else if (type == 1){
vh.rel.setBackgroundColor(ContextCompat.getColor(context!!, R.color.white))
vh.name.setBackgroundColor(ContextCompat.getColor(context!!, R.color.white))
vh.name.setTextColor(ContextCompat.getColor(context!!, R.color.colorPrimary))
vh.separator.visibility = View.VISIBLE
}else{
vh.rel.setBackgroundColor(ContextCompat.getColor(context!!, R.color.white))
vh.name.setBackgroundColor(ContextCompat.getColor(context!!, R.color.white))
vh.name.setTextColor(ContextCompat.getColor(context!!, R.color.colorPrimary))
vh.separator.visibility = View.GONE
}
Actions.overrideFonts(context!!, vh.rel)
return view
}
override fun getItem(position: Int): DrawerItem {
return drawerItems[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getCount(): Int {
return drawerItems.size
}
override fun getItemViewType(position: Int): Int {
if (drawerItems[position].isHeader)
return 0
else if (!drawerItems[position].isLast)
return 1
else
return 2
}
override fun getViewTypeCount(): Int {
return 3
}
}
private class ViewHolder(view: View) {
val rel: RelativeLayout = view.findViewById(R.id.rel) as RelativeLayout
val name: TextView = view.findViewById(R.id.name) as TextView
val separator = view.findViewById<View>(R.id.separator)
}
What should I change, the activity layout, or the adapter or what i realy have no idea.
EDIT
I set the visibility of the marquee text view in the layout to gone, and everything worked just fine, does anybody know why? because I don't want to replace this text view with a horizontal recycler view
SOLVED.
Changed the approach completely, I stopped the marquee and applied cross fade animation to the text view, with a handler that changes the object being set in the text view at each iteration, and now it looks perfect and way more elegnat

how to show full layout in BottomSheetDialog with min and max height 350dp in android

My layout_xml code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="#dimen/_350sdp"
android:maxHeight="#dimen/_500sdp"
android:orientation="vertical"
android:id="#+id/commentProblemScreenLL">
<ListView
android:id="#+id/commentProblemLV"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/commentProblemNotFound"
android:visibility="gone"
android:id="#+id/commentProblemNotFoundTV"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="#dimen/_40sdp"
android:background="#drawable/side_nav_bar"
android:orientation="horizontal"
android:padding="#dimen/m1dp"
android:weightSum="1"
android:layout_alignParentBottom="true">
<EditText
android:id="#+id/commentEditTextET"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.9"
android:background="#null"
android:hint="#string/comment_EditText"
android:padding="5dip"
android:textColor="#color/white"
android:textColorHint="#color/hintcolor" />
<ImageButton
android:id="#+id/commentSendTextIB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.1"
android:layout_alignParentEnd="true"
android:background="#drawable/side_nav_bar"
android:paddingBottom="#dimen/_4sdp"
android:src="#drawable/cm_chat_send"
android:layout_alignParentRight="true"
android:paddingRight="#dimen/_10sdp"
android:layout_marginTop="#dimen/_5sdp"/>
</RelativeLayout>
</RelativeLayout>
Java code:-
private void showCommentDailog()
{
Log.d(TAG,"showCommentDailog enter()");
commentDialog = new BottomSheetDialog(getContext());
View view = ((ProblemsDetailActivity) getActivity()).getLayoutInflater().inflate(R.layout.commentproblemscreen, null);
commentDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
commentProblemLV = (ListView)view.findViewById(R.id.commentProblemLV);
TextView commentProblemNotFoundTV = (TextView)view.findViewById(R.id.commentProblemNotFoundTV);
EditText commentEditTextET = (EditText) view.findViewById(R.id.commentEditTextET);
ImageButton commentSendTextIB = (ImageButton)view.findViewById(R.id.commentSendTextIB);
if(commentDialog.getWindow() != null) {
commentDialog.getWindow().setGravity(Gravity.BOTTOM);
}
//call the function to show list of previous work
commentDialog.setContentView(view);
commentDialog.setCanceledOnTouchOutside(true);
commentDialog.show();
final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from((View) view.getParent());
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
commentDialog.dismiss();
}else{
if (newState != BottomSheetBehavior.STATE_EXPANDED) {
if(commentProblemLV != null && !listIsAtTop()){
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
}
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
});
}
This code does not show the full layout in bottomsheetDailog. Please correct my code as it shows the full layout in bottomsheetDialog.
I want to open full layout in half screen with BottomSheetDialog.
here I should be given my java code also for bottomSheetDialog.
bottomsheetdailog will apear on clickof comment ImageView.

Categories

Resources