I think you're going to need to make a custom layout. This works well for the sample I made and it meets all of the requirements you posted above, but you'll need to add a touch more math the code to account for layout_margins and padding.
The basic idea of what's going on here is I subclassed LinearLayout and in the onMeasure pass, I check to make sure that right view has the option to take up as much space as possible. Note that I have to remeasure the right view and not just get the measured width because linearlayout isn't going to give it enough space. Once you have how much room the right view takes up, check to see if the middle view (called leftView...sorry) is taking up more space than you want. If it does, just give it the space that's left over.
Based upon your requirements of it being in a RecyclerView... I know you said you wanted a pure xml solution, but you're going to get better performance if you tackle it in code as xml 1. may be impossible and 2. will require more computations than just doing it yourself directly.
public class CustomLinearLayout extends LinearLayout {
private View child0;
private TextView leftView, rightView;
public CustomLinearLayout(Context context) {
super(context);
}
public CustomLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (rightView == null) {
child0 = getChildAt(0);
leftView = (TextView)getChildAt(1);
rightView = (TextView) getChildAt(2);
}
int spec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST);
rightView.measure(spec, spec);
int remaining = getMeasuredWidth() - child0.getMeasuredWidth() - rightView.getMeasuredWidth();
if (leftView.getMeasuredWidth() > remaining) {
int specW = MeasureSpec.makeMeasureSpec(remaining, MeasureSpec.AT_MOST);
int specH = MeasureSpec.makeMeasureSpec(leftView.getMeasuredHeight(), MeasureSpec.EXACTLY);
leftView.measure(specW, specH);
}
}
XML layout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.joshua.myapplication.MainActivity">
<com.example.joshua.myapplication.CustomLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:background="#FF0000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textSize="18sp"
android:text="My Left View With Really Really Long Text That should fill the screen"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textSize="18sp"
android:text="My Right View"
/>
</com.example.joshua.myapplication.CustomLinearLayout>
<com.example.joshua.myapplication.CustomLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="20dp">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:background="#FF0000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textSize="18sp"
android:text="My Left View with short text"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textSize="18sp"
android:text="My Right View"
/>
</com.example.joshua.myapplication.CustomLinearLayout>
</LinearLayout>