I need to use IPhone like segmented control in Android. Is there a default control for the same? What might be the best and efficient way to do so?
I have achieved it using build in Views.
MySegmentActivity
public class SegmentActivity extends AppCompatActivity implements View.OnClickListener {
private Context mContext;
private List<Button> buttonList = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.item_segment_layout);
mContext = SegmentActivity.this;
initSegmentButtons();
}
private void initSegmentButtons() {
buttonList = new ArrayList<>();
Button dayBtn = (Button) findViewById(R.id.btn_day);
Button weekBtn = (Button) findViewById(R.id.btn_week);
Button monthBtn = (Button) findViewById(R.id.btn_month);
dayBtn.setOnClickListener(this);
weekBtn.setOnClickListener(this);
monthBtn.setOnClickListener(this);
buttonList.add(dayBtn);
buttonList.add(weekBtn);
buttonList.add(monthBtn);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_day:
buttonList.get(0).setBackgroundResource(R.drawable.btn_bg_orange_selected);
buttonList.get(1).setBackgroundResource(R.drawable.btn_bg_orange);
buttonList.get(2).setBackgroundResource(R.drawable.btn_bg_orange);
break;
case R.id.btn_week:
buttonList.get(0).setBackgroundResource(R.drawable.btn_bg_orange);
buttonList.get(1).setBackgroundResource(R.drawable.btn_bg_orange_selected);
buttonList.get(2).setBackgroundResource(R.drawable.btn_bg_orange);
break;
case R.id.btn_month:
buttonList.get(0).setBackgroundResource(R.drawable.btn_bg_orange);
buttonList.get(1).setBackgroundResource(R.drawable.btn_bg_orange);
buttonList.get(2).setBackgroundResource(R.drawable.btn_bg_orange_selected);
break;
default:
break;
}
}
}
layout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:orientation="horizontal">
<Button
android:id="@+id/btn_day"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_bg_orange"
android:gravity="center"
android:text="Day"
android:textColor="@android:color/white"
android:textSize="20sp" />
<Button
android:id="@+id/btn_week"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="-1dp"
android:layout_marginRight="-1dp"
android:layout_weight="1"
android:background="@drawable/btn_bg_orange"
android:gravity="center"
android:text="Week"
android:textColor="@android:color/white"
android:textSize="20sp" />
<Button
android:id="@+id/btn_month"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_bg_orange_selected"
android:gravity="center"
android:text="Month"
android:textColor="@android:color/white"
android:textSize="20sp" />
</LinearLayout>
btn_bg_orange.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="@color/orange" />
<solid android:color="@android:color/transparent" />
</shape>
btn_bg_orange_selected
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="@color/orange" />
<solid android:color="@color/orange" />
</shape>
For a modern iOS-styled SegmentedControl, you can consider using: https://github.com/alanvan0502/segmented-control-group
You can achieve segmented control functionality with Radio Group
Here are few examples this and Hello Form
I have created a SegmentCustomControl for Android.
SegmentTestActivity.class
public class SegmentTestActivity extends AppCompatActivity {
private Context mContext;
private SegmentView segmentView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.segment_test_activity);
mContext = SegmentTestActivity.this;
segmentView = (SegmentView) findViewById(R.id.segment_view);
segmentView.setOnSegmentSelectedListener(new OnSegmentSelectedListener() {
@Override
public void onSegmentSelected(int position) {
Toast.makeText(mContext, "Segment selected at Index : " + position, Toast.LENGTH_SHORT).show();
}
});
}
}
segment_test_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<custom.rnd.SegmentView
android:id="@+id/segment_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
app:numberOfSegment="3"
app:segmentColor="@color/colorPrimary"
app:selectedTextColor="@android:color/black"
app:textSize="16sp"
app:unSelectedTextColor="@color/colorPrimary" />
<custom.rnd.SegmentView
android:id="@+id/segment_view2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
app:numberOfSegment="2"
app:segmentColor="@color/colorAccent"
app:selectedTextColor="@android:color/black"
app:titlesOfSegment="New,OLD"
app:unSelectedTextColor="@android:color/white" />
</RelativeLayout>
SegmentView
public class SegmentView extends LinearLayout{
public static final String TAG = "SegmentView";
private OnSegmentSelectedListener onSegmentSelectedListener;
private SegmentView segmentView;
private int numberOfSegments = 0;
private List<String> titlesOfSegment;
private int selectedTextColor;
private int unSelectedTextColor;
private int segmentColorSelected;
/*private int defaultSelectedColor = Color.parseColor("#c13d1f");
private int defaultUnSelectedColor = Color.parseColor("#ea8d21");*/
public SegmentView(Context context, AttributeSet attrs) {
super(context, attrs);
initLayout(context, attrs);
}
public SegmentView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initLayout(context, attrs);
}
private void initLayout(Context mContext, AttributeSet attrs) {
segmentView = this;
titlesOfSegment = new ArrayList<>();
TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.SegmentView);
numberOfSegments = typedArray.getInt(R.styleable.SegmentView_numberOfSegment, 0);
String titleWithComma = typedArray.getString(R.styleable.SegmentView_titlesOfSegment);
selectedTextColor = typedArray.getColor(R.styleable.SegmentView_selectedTextColor, Color.WHITE);
unSelectedTextColor = typedArray.getColor(R.styleable.SegmentView_unSelectedTextColor, Color.parseColor("#c13d1f"));
segmentColorSelected = typedArray.getColor(R.styleable.SegmentView_segmentColor, 0);
//orientation = typedArray.getInt(R.styleable.SegmentView_orientation , 0);
int unitsTextSize = typedArray.getDimensionPixelSize(R.styleable.SegmentView_textSize, 0);
if (titleWithComma != null && !titleWithComma.isEmpty()) {
String[] arrayOfTitles = titleWithComma.split(",");
for (String x : arrayOfTitles) {
titlesOfSegment.add(x);
}
}
typedArray.recycle();
segmentView.setOrientation(HORIZONTAL);
/*if(orientation == 0){
segmentView.setOrientation(HORIZONTAL);
}
else{
segmentView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
segmentView.setOrientation(VERTICAL);
}*/
for (int i = 0; i < numberOfSegments; i++) {
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 1.0f);
/*if(orientation != 0)
param = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT,1.0f);*/
Button btn = new Button(mContext);
if (titlesOfSegment != null && titlesOfSegment.size() == numberOfSegments)
btn.setText(titlesOfSegment.get(i));
else
btn.setText("Segment " + i);
btn.setTextColor(Color.WHITE);
if(unitsTextSize != 0){
btn.setTextSize(TypedValue.COMPLEX_UNIT_PX, unitsTextSize);
}
else
btn.setTextSize(14.0f);
if (i == 0) {
btn.setBackgroundResource(R.drawable.btn_bg_orange_selected);
btn.setTextColor(selectedTextColor);
updateBorderAndSolidColor(btn);
} else {
btn.setBackgroundResource(R.drawable.btn_bg_orange);
btn.setTextColor(unSelectedTextColor);
if (segmentColorSelected != 0) {
//changeSolidColor(btn ,segmentColorUnSelected);
changeStrokeColor(btn, segmentColorSelected);
}
}
final int x = i;
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (onSegmentSelectedListener != null)
onSegmentSelectedListener.onSegmentSelected(x);
handleClick(x, view);
}
});
segmentView.addView(btn, param);
}
}
private void updateBorderAndSolidColor(Button btn) {
if (segmentColorSelected != 0) {
changeStrokeColor(btn, segmentColorSelected);
}
if (segmentColorSelected != 0) {
changeSolidColor(btn, segmentColorSelected);
}
}
public void setOnSegmentSelectedListener(OnSegmentSelectedListener onSegmentSelectedListener) {
this.onSegmentSelectedListener = onSegmentSelectedListener;
}
private void handleClick(int position, View view) {
Button btnView = null;
for (int iter = 0; iter < segmentView.getChildCount(); iter++) {
btnView = (Button) segmentView.getChildAt(iter);
if (iter == position) {
btnView.setBackgroundResource(R.drawable.btn_bg_orange_selected);
btnView.setTextColor(selectedTextColor);
updateBorderAndSolidColor(btnView);
} else {
btnView.setBackgroundResource(R.drawable.btn_bg_orange);
btnView.setTextColor(unSelectedTextColor);
if (segmentColorSelected != 0)
changeStrokeColor(btnView, segmentColorSelected);
}
}
}
private void changeStrokeColor(Button view, int colorCode) {
GradientDrawable drawable = (GradientDrawable) view.getBackground();
//update value 3 according to your need.
drawable.setStroke(3, colorCode); // set stroke width and stroke color
}
private void changeSolidColor(Button view, int colorCode) {
GradientDrawable drawable = (GradientDrawable) view.getBackground();
drawable.setColor(colorCode); // set solid color
}
}
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SegmentView">
<attr name="numberOfSegment" format="integer" />
<attr name="titlesOfSegment" format="string" />
<attr name="selectedTextColor" format="color" />
<attr name="unSelectedTextColor" format="color" />
<attr name="segmentColor" format="color" />
<attr name="textSize" format="dimension" />
<!--<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>-->
</declare-styleable>
</resources>
and Listener
public interface OnSegmentSelectedListener {
void onSegmentSelected(int position);
}
What you are looking for is MaterialButtonToggleGroup, and you can put in some Material Button. It is pretty similar to iOS UISegmentContorol.
It looks like this:
source with example: https://material.io/develop/android/components/buttons#toggle-button