0

I want the user to be able to customize the UI of the app such as allowing the user to configure the shape of the profile pics to either circles or squares. What is the best way to achieve this?

  • I wish to avoid having two layout files which will have most of the stuff common and inflating them depending on the setting as it would mean changing the same stuff twice in the future.
  • I want to use Data Binding if possible. Eg. Setting the value of the variable in the XML file depending on the setting and including the correct profile pic layout depending on that variable.
Utkarsh Barsaiyan
  • 335
  • 1
  • 2
  • 11
  • You can implement the selector and style attributes apply this style. What I mean is apply the style according to the change of state/variable value. You can get examples on the internet for the same. – Ishtdeep Hora Jan 19 '19 at 05:39
  • https://developer.android.com/training/custom-views/making-interactive have you tried reading the docs? make a custom view – Karan Harsh Wardhan Jan 19 '19 at 06:20
  • @KaranHarshWardhan that is a totally different thing imo – Utkarsh Barsaiyan Jan 19 '19 at 14:38
  • @IshtdeepHora Using selectors seem like a nice solution but the states only depend on things like pressed, activated, selected etc. So, how can I link it with a global config? – Utkarsh Barsaiyan Jan 19 '19 at 14:51
  • @UtkarshBarsaiyan You can do that using attr.xml declare them within your declare-styleable attribute. Now you can access the attr within your selector with global access using app namespace. See the second answer on the below link : https://stackoverflow.com/questions/4336060/how-to-add-a-custom-button-state – Ishtdeep Hora Jan 20 '19 at 04:34
  • @IshtdeepHora Sorry, but I cannot understand much from your comment or the link. Please see my answer. Does your method solve the problem that I have mentioned in the last part of my answer? Or is it an altogether different and better method? – Utkarsh Barsaiyan Jan 20 '19 at 17:15

1 Answers1

1

After more than a week of persistently trying, I came up with an elegant solution:

In the XML, I used data binding:

<data>
        <variable
            name="shape"
            type="chat.rocket.android.helper.Constants"/>
</data>
...
<com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/image_avatar"
            android:layout_width="40dp"
            android:layout_height="40dp"
            app:roundedCornerRadius='@{shape.AVATAR_SHAPE_CIRCLE ? @dimen/circle_avatar_corner_radius : @dimen/square_avatar_corner_radius}' />

As roundedCornerRadius does not have a corresponding setRoundedCornerRadiusIn BindingAdapters.kt,

@BindingAdapter("roundedCornerRadius")
fun setRoundedCornerRadius(view: SimpleDraweeView, height: Float) {
    val roundingParams = RoundingParams.fromCornersRadius(height)
    view.hierarchy.roundingParams = roundingParams
} 

The Constants.kt file has the constant which can be configured to change the shape:

object Constants {
    ...
    const val AVATAR_SHAPE_CIRCLE = true
}

In RecyclerViewAdapter,

...
val layoutInflater = LayoutInflater.from(parent.context)
val binding: ViewDataBinding = DataBindingUtil.inflate(layoutInflater, R.layout.item_contact, parent, false)
ContactViewHolder(binding.root)
...

This is the best solution I could come up with. It would be great if there is a way to apply multiple attributes depending on the value of the shape.AVATAR_SHAPE_CIRCLE. Eg.

if(shape.AVATAR_SHAPE_CIRCLE)
    apply these attr
else
    apply these attr

Suggestions are welcome!

Utkarsh Barsaiyan
  • 335
  • 1
  • 2
  • 11