Can't change GridView dynamically - android

I'm developing an app. In this app there's an alertdialog that opens when you click a point.
In this alert dialog there are two edittext, a gridview and a button. The gridview has associated a BaseAdapter that convert Uris to IconView (a class that extends ImageView) using Glide.
I want to set a maximum height of 350dp, but if there is just one row (there'll be always one image) I want the gridview to adapt.
I tried this way: How to have a GridView that adapts its height when items are added
But it doesn't work. So what I've tried is to count the number of elements and if there's is more than 2, set 350dp of height if there is less than 2, set 175dp. But it doesnt work.
The alert dialog layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="#+id/puntoName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:fontFamily="sans-serif"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/puntoDescripcion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:maxHeight="100dp"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/puntoName" />
<GridView
android:id="#+id/photo_grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:gravity="center"
android:horizontalSpacing="6dp"
android:numColumns="2"
android:verticalSpacing="5dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/puntoDescripcion"></GridView>
<Button
android:id="#+id/cerrar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cerrar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/photo_grid" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is the code I'm using in order to change GridView height:
fun checkSize() {
val popUp: View = fragmentCaller.layoutInflater.inflate(R.layout.popup,null)
var photogrid: GridView = popUp.findViewById(R.id.photo_grid)
var params: ViewGroup.LayoutParams = photogrid.layoutParams
var tam: Int = 175
if (adapter.getDataSource().size>2) {
tam = DpToPixels(350)
}
photogrid.layoutParams.height = tam
photogrid.requestLayout()
}
private fun DpToPixels(dp: Int) : Int {
val escala: Float = fragmentCaller.requireContext().resources.displayMetrics.density;
var tam: Int = (dp * escala + 0.5f).toInt()
return tam
}
The size of the gridView is always 0. I don't know why. I just want to set android:layout_height programmatically. I call checkSize() method after I call Dialog.show() and everytime I do changes in the elements of adapter.
Thanks.

Related

Show RecyclerView/PopupWIndow by anchoring below or above edittext depending on where the cursor is and depending on screen available height

I am trying to display # user mentions like facebook or twitter. I am able to implement this functionality. But i have a ui problem.
If edittext is at the bottom of the screen i need to show suggestion in recyclerview at the top.(above edittext cursor)
If edittext is at the top of the screen i need to show suggestion in recycelrview at the bottom (below edittext cursor)
What have i tried?
I have used recyclerview that is constrained below edittext
Problem
When soft keyboard opens it covers the recyclerview. This happens when edittext cursor is at the bottom.
How can i fix this using existing recyclerview itself?.
When edittext cursor is at the top see suggestions are shown below properly.
Code
<?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">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textStyle="bold"
android:textSize="16sp"
android:textColor="#color/black"
android:fontFamily="#font/source_sans_pro"
android:id="#+id/titleHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="#string/create_feed_post"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="16dp"
android:background="#c8c8c8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/titleHeader" />
<com.linkedin.android.spyglass.ui.MentionsEditText
android:padding="8dp"
android:id="#+id/mentionsEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="300dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="#null"
android:gravity="start|top"
android:hint="Share team wins or recognize colleague for a job well done"
android:inputType="textMultiLine"
android:minHeight="50dp"
android:paddingStart="15dp"
android:paddingEnd="15dp"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/line">
</com.linkedin.android.spyglass.ui.MentionsEditText>
<ImageView
android:id="#+id/preview"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/mentionsEditText" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/list"
android:layout_width="0dp"
android:layout_height="250dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:elevation="5dp"
android:orientation="vertical"
android:overScrollMode="never"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="none"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/mentionsEditText" />
<View
android:id="#+id/line2"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="8dp"
android:background="#c8c8c8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/preview" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/optionsContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/line2">
<ImageView
android:id="#+id/visibility"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:src="#drawable/toggle_comment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#+id/attach"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/attach"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_upload_image" />
<Button
android:id="#+id/done"
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_marginStart="32dp"
android:text="#string/post"
android:textAllCaps="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="#id/visibility"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="#id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toBottomOf="#+id/titleHeader"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#+id/titleHeader"
app:srcCompat="#drawable/ic_close"
app:tint="#color/black" />
<FrameLayout
android:visibility="gone"
android:elevation="5dp"
android:id="#+id/container"
app:layout_constraintBottom_toTopOf="#+id/preview"
app:layout_constraintEnd_toEndOf="#+id/preview"
app:layout_constraintTop_toTopOf="#+id/preview"
android:layout_width="20dp"
android:layout_height="20dp">
<com.mikhaellopez.circleview.CircleView
app:cv_border_width="1dp"
app:cv_border_color="#EAEAEA"
app:cv_border="true"
app:cv_color="#color/white"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:layout_gravity="center"
android:id="#+id/removePreview"
android:layout_width="15dp"
android:layout_height="15dp"
app:srcCompat="#drawable/ic_close"
app:tint="#999999" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</layout>
Update: i tried using a pop up window. I am able to show above or below a view depending on where the view is located. But there is still one problem with keyboard opening. The pop up comes over the keyboard when the edittext is at the bottom. The edittext moves up but popup window stays in same place
Update 2:
if(anchor instanceof EditText) {
EditText editText = (EditText) anchor;
int pos = editText.getSelectionStart();
Layout layout = editText.getLayout();
int line = layout.getLineForOffset(pos);
int baseline = layout.getLineBaseline(line);
int ascent = layout.getLineAscent(line);
float cursorx = layout.getPrimaryHorizontal(pos);
cursory = baseline + ascent- editText.getScrollY();
}
final View contentView = view;
final Rect windowRect = new Rect();
contentView.getWindowVisibleDisplayFrame(windowRect);
final int windowW = windowRect.width();
final int windowH = windowRect.height();
contentView.measure(
makeDropDownMeasureSpec(getWidth(), windowW),
makeDropDownMeasureSpec(getHeight(), windowH)
);
final int measuredW = contentView.getMeasuredWidth();
final int measuredH = contentView.getMeasuredHeight();
final int[] anchorLocation = new int[2];
anchor.getLocationInWindow(anchorLocation);
final int anchorBottom = anchorLocation[1] + anchor.getHeight();
if (y + anchorBottom < 0) {
y = -anchorBottom;
} else {
y = (int) (y + cursory );
}
And then
popupWindow.showAsDropDown(anchor, 0, y);
and the flag in manifest is
android:windowSoftInputMode="adjustResize"
Using pop up window show at location will fix this
private fun showPopupWindow(anchor: View) {
var popUpHeight = 0
PopupWindow(anchor.context).apply {
isOutsideTouchable = true
val inflater = from(anchor.context)
contentView = inflater.inflate(R.layout.popup_layout, null).apply {
measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
)
measuredWidth
measuredHeight
popUpHeight = measuredHeight
}
height = ViewGroup.LayoutParams.WRAP_CONTENT
width = ViewGroup.LayoutParams.MATCH_PARENT
}.also { popupWindow ->
val location = IntArray(2).apply {
anchor.getLocationInWindow(this)
}
val size = Size(
popupWindow.contentView.measuredWidth,
popupWindow.contentView.measuredHeight
)
val editText = anchor as EditText
val pos = editText.selectionStart
val layout: Layout = editText.layout
val line: Int = layout.getLineForOffset(pos)
editText.getLocationOnScreen(location)
val point = Point()
point.x = layout.getPrimaryHorizontal(pos).toInt()
point.y = layout.getLineBottom(line)// location[1] //- (baseline + ascent )
val y = point.y
val top = layout.getLineTop(line)
val editTextheight = editText.measuredHeight
val yOffset = if (y > (editTextheight / 2)) {
top - (popUpHeight + 50)
} else {
point.y + 50
}
popupWindow.showAsDropDown(
anchor, 0,
yOffset
)
}
}
Based on where the cursor is and also the height of edittext you can calculate the yoffset and show the pop up at a specified position.
In case edittext scrolls you can use editText.scrolly and re-calculate your offset.

How to add textview to ConstraintLayout programatically?

There's similar questions, but I haven't been able to find any as of yet that get into the basics.
I'm making a to-do list application and I want it so that when I click the plus button, the user is asked for text and the item is displayed on the screen. Once the text is recieved from the user, I'm not sure how you put this into a textview. add that textview into a constraintlayout(activity_main.xml) and align it with another textview (menutitletext) so that it doesn't default to 0,0. I haven't been able to add code since I genuinely don't know where to start - the answers either are adding imageviews, are in Kotlin or are using a relativelayout. I'd appreciate any help on this.
Someone asked for my design - I think this is what you wanted ?
<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">
<View
android:id="#+id/divider"
android:layout_width="393dp"
android:layout_height="2dp"
android:layout_marginTop="28dp"
android:background="#000000"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/menuaddbutton" />
<ImageButton
android:id="#+id/menusettingsbutton"
android:layout_width="65dp"
android:layout_height="55dp"
android:layout_marginStart="11dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="20dp"
android:src="#drawable/test1w"
app:layout_constraintBottom_toTopOf="#+id/divider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="#+id/menutrashbutton"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.235" />
<ImageButton
android:id="#+id/menutrashbutton"
android:layout_width="60dp"
android:layout_height="65dp"
android:layout_marginStart="12dp"
android:layout_marginTop="30dp"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toTopOf="#+id/divider"
app:layout_constraintStart_toEndOf="#+id/menuaddbutton"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="#drawable/test1d" />
<ImageButton
android:id="#+id/menuaddbutton"
android:layout_width="78dp"
android:layout_height="59dp"
android:layout_marginStart="22dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="156dp"
android:layout_marginBottom="20dp"
android:background="#android:color/background_light"
app:layout_constraintBottom_toTopOf="#+id/divider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="#+id/menueditbutton"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.6"
app:srcCompat="#drawable/test1z" />
<ImageButton
android:id="#+id/menueditbutton"
android:layout_width="59dp"
android:layout_height="59dp"
android:layout_marginStart="80dp"
android:layout_marginTop="30dp"
android:layout_marginBottom="20dp"
android:background="#android:color/background_light"
android:onClick="edittitle"
app:layout_constraintBottom_toTopOf="#+id/divider"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="#drawable/test1f" />
<TextView
android:id="#+id/menutitletext"
android:layout_width="366dp"
android:layout_height="36dp"
android:layout_marginStart="12dp"
android:layout_marginTop="15dp"
android:gravity="center_horizontal"
android:text="#string/menutitleempty"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/divider" />
</androidx.constraintlayout.widget.ConstraintLayout>
You can use same concept as in here https://stackoverflow.com/a/40527407/3904645
It adds views to ConstraintLayout programmatically and aligns them with programmatic constraints. This is what you need I believe.
For your case
set.connect(childView.getId(), ConstraintSet.TOP, parentLayout.getId(),
ConstraintSet.TOP, 60);
change parentLayout.getId() with the last list item that you have added. You can track what is the last view with some instance variable.
class MainActivity : AppCompatActivity() {
lateinit var parentLayout: ConstraintLayout
var lastView: View? = null
var numberIfViews = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
parentLayout = findViewById<View>(R.id.constraint_layout) as ConstraintLayout
lastView = parentLayout
}
fun addTextView(text: String) {
val set = ConstraintSet()
val childView = TextView(this)
childView.id = View.generateViewId()
childView.text = text
parentLayout.addView(childView, numberIfViews)
set.clone(parentLayout)
set.connect(
childView.id,
ConstraintSet.TOP,
lastView!!.id,
ConstraintSet.TOP,
60
)
set.applyTo(parentLayout)
numberIfViews++
lastView = childView
}
}
Have not tested it but it should work
ConstraintLayout parentLayout = (ConstraintLayout)findViewById(R.id.mainConstraint);
TextView tt= new TextView (this);
// set view id, else getId() returns -1
childView.setId(View.generateViewId());
layout.addView(tt, 0);
you can try this way

ChatKit library : incoming image wrong margins

I'm using ChatKit library (https://github.com/stfalcon-studio/ChatKit/) for a chat feature in my app.
In the message list provided by the library, I also included images messages.
It works fine, but the bubble's layout of the images is ambiguous, as the following picture :
Bubble picture 1 and 3 should be aligned on the right side, but they are stick on the left in the available space for incoming messages.
Note that the default text messages bubbles are displayed correctly on
the right.
I didn't find any attributes for the layout in the library to configure this behaviour.
This is my XML for the message list :
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_comments"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.stfalcon.chatkit.messages.MessagesList
android:id="#+id/messagesList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/input_comment"
app:incomingDefaultBubbleColor="#color/lightGrayRetail"
app:incomingTimeTextColor="#color/white"
app:incomingDefaultBubblePressedColor="#color/lightGrayRetail"
app:incomingDefaultImageOverlayPressedColor="#color/lightGrayRetail"
app:outcomingDefaultBubblePressedColor="#color/pinkRetail"
app:outcomingDefaultImageOverlayPressedColor="#color/pinkRetail"
app:outcomingDefaultBubbleColor="#color/pinkRetail"
app:outcomingTimeTextColor="#color/colorMaterialGray" />
</android.support.v4.widget.SwipeRefreshLayout>
My incoming text message layout layout :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp">
<TextView
android:id="#+id/displayNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/bubble"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:textColor="#color/colorMaterialGray"/>
<de.hdodenhof.circleimageview.CircleImageView
android:id="#id/messageUserAvatar"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="8dp"
android:src="#drawable/woman" />
<ImageView
android:id="#+id/onlineIndicator"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_alignEnd="#id/messageUserAvatar"
android:layout_alignTop="#id/messageUserAvatar"
android:layout_marginEnd="5dp" />
<LinearLayout
android:id="#id/bubble"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="30dp"
android:layout_below="#+id/displayNameTextView"
android:layout_toEndOf="#id/messageUserAvatar"
android:orientation="vertical">
<TextView
android:id="#id/messageText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_marginStart="8dp"/>
</LinearLayout>
<TextView
android:id="#+id/incomingTimeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#id/bubble"
android:layout_below="#id/bubble"
android:layout_marginEnd="4dp"
android:text="18:00"
android:layout_marginTop="4dp"
android:textColor="#color/colorMaterialGray" />
</RelativeLayout>
Outcoming layout :
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp">
<LinearLayout
android:id="#id/bubble"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginStart="40dp"
android:orientation="vertical">
<TextView
android:id="#id/messageText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<TextView
android:id="#+id/outcomingTimeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#id/bubble"
android:layout_below="#id/bubble"
android:textColor="#color/colorMaterialGray"
android:layout_marginStart="16dp"/>
</RelativeLayout>
MessageHolder of outcoming :
public class CustomOutcomingMessageViewHolder extends MessageHolders.OutcomingTextMessageViewHolder<Comment> {
private TextView mOutcomingTimeTextView;
public CustomOutcomingMessageViewHolder(View itemView) {
super(itemView);
mOutcomingTimeTextView = itemView.findViewById(R.id.outcomingTimeTextView);
}
#Override
public void onBind(Comment comment) {
super.onBind(comment);
if(comment.getmContent() != null){
if(comment.getmContent().length() > 3){
SimpleDateFormat timeOutput = new SimpleDateFormat("HH:mm", Locale.FRANCE);
String commentPostedTime = timeOutput.format(comment.getmPostedDate());
mOutcomingTimeTextView.setText(commentPostedTime);
}
}
}
}
Any ideas ?
This happened to me without using any MessageHolder, I could fix it by assigning the same width to all images:
int width = Math.round( (float) getScreenWidthHeight().x * 0.8f); // width = 80% of screen's max width
int height = Math.round((float) bitmap.getHeight() / ((float) bitmap.getWidth() / (float) width));
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap), width, height, true);
where getScreenWidthHeight() is:
private Point getScreenWidthHeight(Activity activity) {
Display display = activity.getWindowManager(). getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size;
}
Did you check the sender ids in your code to be different for sender and receiver side by the id which is gotten from getId of message model? According to the library you need to determine the senderId in the Adapter initialization:
MessagesListAdapter<Message> adapter = new MessagesListAdapter<>(senderId,
imageLoader);
messagesList.setAdapter(adapter);
Library decides whether to align left or right according to senderIds comparison.
For anyone using the default MessagesListAdapter and ViewHolders, outgoing picture message ImageViews don't have their alignment set, but their parent view width is set to match_parent, which is why the image isn't aligned correctly.
item_outcoming_image_message.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp">
<com.stfalcon.chatkit.utils.RoundedImageView
android:id="#id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_marginLeft="#dimen/message_outcoming_bubble_margin_left"
android:layout_marginStart="#dimen/message_outcoming_bubble_margin_left" />
So, after looking through some of the library code, I found one solution is to simply override onBindViewHolder():
messagesAdapter = new MessagesListAdapter<Message>(senderId, imageLoader) {
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
if (holder.getItemViewType() == -132) { // -132 is an outgoing picture message
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.itemView.findViewById(com.stfalcon.chatkit.R.id.image).getLayoutParams();
params.addRule(RelativeLayout.ALIGN_PARENT_END);
}
}
};
Fixed it by setting a fixed width using ConstraintLayout
val holdersConfig = MessageHolders()
.setIncomingTextConfig(
CustomIncomingTextMessageViewHolder::class.java,
R.layout.item_custom_incoming_text_message
)
Here is my item_custom_outcoming_image_message
<?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:id="#+id/imageMessageContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="8dp"
tools:context=".chatting.ChattingFragment">
<com.stfalcon.chatkit.utils.RoundedImageView
android:id="#id/image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="#drawable/ic_chat_pick_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent=".8"
tools:srcCompat="#tools:sample/backgrounds/scenic" />
<View
android:id="#id/imageOverlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="#id/image"
app:layout_constraintEnd_toEndOf="#id/image"
app:layout_constraintStart_toStartOf="#id/image"
app:layout_constraintTop_toTopOf="#id/image"
tools:visibility="gone" />
<ImageView
android:id="#+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/image"
tools:src="#drawable/ic_message_status_processing" />
<TextView
android:id="#id/messageTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="#id/status"
app:layout_constraintEnd_toStartOf="#+id/status"
app:layout_constraintTop_toTopOf="#id/status"
tools:text="12:15" />
</androidx.constraintlayout.widget.ConstraintLayout>

Access buttons from layout programmatically inflated within another layout

I am inflating a list of layouts programmatically from a xml into another layout.
The end result looks like the following image.
The number of checkboxes is different on each run, how can i get their state and also add listeners to the image button? Ideally i want only one listener that has an id of the selected layout.
This is the xml code.
<?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:id="#+id/chk_item_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:id="#+id/checkBox_chkitem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView_chkitem"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="24dp"
android:text="TextView"
app:layout_constraintEnd_toStartOf="#+id/imageButton_chkitem"
app:layout_constraintStart_toEndOf="#+id/checkBox_chkitem"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="#+id/imageButton_chkitem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#android:drawable/stat_notify_more" />
</android.support.constraint.ConstraintLayout>
And this is how i inflate the layouts
val checkitemlist = listOf<ChecklistItem>(ChecklistItem("Categoria", "conteudo"),
ChecklistItem("Categoria", "conteudo"),
ChecklistItem("Categoria", "conteudo"),
ChecklistItem("Categoria", "conteudo"))
for (item in checkitemlist) {
val inflater = LayoutInflater.from(context)
val layout = inflater.inflate(io.ubivis.ier.R.layout.checklistitem_layout, null, false) as ConstraintLayout
layout.textView_chkitem.text = item.textSimple
checklist_content_layout.addView(layout)
}
replace your code
for (item in checkitemlist) {
checklist_content_layout.removeAllViews()
val inflater = LayoutInflater.from(context)
val layout = inflater.inflate(io.ubivis.ier.R.layout.checklistitem_layout, null, false) as ConstraintLayout
layout.textView_chkitem.text = item.textSimple
checklist_content_layout.addView(layout)
}

Add view to constraintLayout with constraints similar to another child

I have a constraint layout (alpha9) with views spread all over it, and I have one particular ImageView that I need to replicate and add more of like it.
The layout is like so :
The main purpose is to animate 5 of those "coin" imageViews when the button is pressed. The imageViews i need to generated sha'll have exact properties of the the imageView behind the Button down below (with same constraints)
What i tried to do is the following :
private ImageView generateCoin() {
ImageView coin = new ImageView(this);
constraintLayout.addView(coin,-1,originCoinImage.getLayoutParams());//originCoinImage is the imageView behind the button
coin.setImageResource(R.drawable.ic_coin);
coin.setScaleType(ImageView.ScaleType.FIT_XY);
coin.setVisibility(View.VISIBLE);
return coin;
}
And it failed. EDIT: It failed to show what i wanted , sometimes it shows a coin in the top left of the screen , sometimes it doesn't show anything but either way , the number of coins increments (meaning the animation is trying to actually do something and then calling the onAnimationFinished method)
I used for animation the library EasyAndroidAnimations
the code is as follows :
MainActivity.java
#OnClick(R.id.addCoin)
public void addCoin() {
// for (int x = 0 ; x < 5 ; x++){
final View newCoin = generateCoin();
sendCoin(newCoin, 300, new AnimationListener() {
#Override
public void onAnimationEnd(com.easyandroidanimations.library.Animation animation) {
incrementCoins();
constraintLayout.removeView(newCoin);
shakeCoin(targetCoinImage, 200, null);
}
});
// }
}
private void incrementCoins() {
coins++;
coinNumber.setText(String.valueOf(coins));
}
private void sendCoin(View coinView, long duration, AnimationListener listener) {
new TransferAnimation(coinView)
.setDestinationView(targetCoinImage)
.setDuration(duration)
.setInterpolator(new AccelerateDecelerateInterpolator())
.setListener(listener)
.animate();
}
private void shakeCoin(View coinView, long duration, AnimationListener listener) {
new ShakeAnimation(coinView)
.setDuration(duration)
.setShakeDistance(6f)
.setNumOfShakes(5)
.setListener(listener)
.animate();
}
activity_main.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:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="seaskyways.canvasanddrawtest.MainActivity">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="Coins : "
android:textSize="30sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/coinNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="16dp"
android:layout_marginStart="8dp"
android:text="0"
android:textColor="#color/colorPrimary"
android:textSize="50sp"
android:textStyle="normal|bold"
app:layout_constraintBottom_toBottomOf="#+id/textView"
app:layout_constraintLeft_toRightOf="#+id/textView"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="#+id/textView" />
<ImageView
android:id="#+id/coinOrigin"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="#+id/addCoin"
app:layout_constraintLeft_toLeftOf="#+id/addCoin"
app:layout_constraintTop_toTopOf="#+id/addCoin"
app:srcCompat="#drawable/ic_coin"
app:layout_constraintRight_toRightOf="#+id/addCoin" />
<ImageView
android:id="#+id/coinTarget"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="#+id/coinNumber"
app:layout_constraintLeft_toRightOf="#+id/coinNumber"
app:layout_constraintTop_toTopOf="#+id/coinNumber"
app:srcCompat="#drawable/ic_coin" />
<Button
android:id="#+id/addCoin"
android:layout_width="0dp"
android:layout_height="75dp"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:text="Button"
android:textAlignment="center"
android:textSize="36sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
ConstraintLayout.LayoutParams cache its parameters, and is associated to the widget you use it on, so you cannot simply pass one widget's layoutParams to another.
You have to instead generate a new layoutParams for your new object, and copy the corresponding fields.
For example, if you have something like:
<?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:id="#+id/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="16dp" />
</android.support.constraint.ConstraintLayout>
Then you could do:
ConstraintLayout layout = (ConstraintLayout) findViewById(R.id.content_main);
ConstraintLayout.LayoutParams params =
(ConstraintLayout.LayoutParams) button.getLayoutParams();
Button anotherButton = new Button(this);
ConstraintLayout.LayoutParams newParams = new ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT);
newParams.leftToLeft = params.leftToLeft;
newParams.topToTop = params.topToTop;
newParams.leftMargin = params.leftMargin;
newParams.topMargin = params.topMargin;
layout.addView(anotherButton, -1, newParams);
This would put the second button exactly in the same place as the one defined in XML.

Categories

Resources