Android SegmentedControl + multi row support

Overview

Android SegmentedControl + multi row support + multi selection

minSdk API 14+

N|Solid

Demo App, Play store link

Or try demo App online !

License

Segmented control for Android, with a lot of customization properties

ScreenShots

Download

Gradle

Add to project level build.gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Add dependency to app module level build.gradle

dependencies {
    implementation 'com.github.RobertApikyan:SegmentedControl:1.2.0'
}

Maven

<repositories>
	<repository>
	    <id>jitpack.io</id>
	    <url>https://jitpack.io</url>
	</repository>
</repositories>

Add dependency

<dependency>
    <groupId>com.github.RobertApikyan</groupId>
    <artifactId>SegmentedControl</artifactId>
    <version>1.1.3</version>
</dependency>

Done.

Simple usage in XML

<segmented_control.widget.custom.android.com.segmentedcontrol.SegmentedControl
                android:id="@+id/segmented_control"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="8dp"
                app:columnCount="3"				       
                app:distributeEvenly="true"
                app:textVerticalPadding="6dp"
                app:radius="12dp"
                app:segments="@array/your_array_data" />

Attributes

     <attr name="supportedSelectionsCount" format="boolean" /> setSupportedSelectionsCount(int)
     <attr name="reselectionEnabled" format="boolean" /> setDistributeEvenly(boolean)
     <attr name="distributeEvenly" format="boolean" /> setDistributeEvenly(boolean)
     <attr name="columnCount" format="integer" /> setColumnCount(int)
     <attr name="segments" format="reference" /> addSegments(Object[]), addSegments(List)
     <attr name="selectedStrokeColor" format="color" /> setSelectedStrokeColor(int)
     <attr name="unSelectedStrokeColor" format="color" /> setUnSelectedStrokeColor(int)
     <attr name="strokeWidth" format="dimension" / setStrokeWidth(int)
     <attr name="selectedBackgroundColor" format="color" /> setSelectedBackgroundColor(int)
     <attr name="unSelectedBackgroundColor" format="color" /> setUnSelectedBackgroundColor(int)
     <attr name="selectedTextColor" format="color"/> setSelectedTextColor(int)
     <attr name="unSelectedTextColor" format="color"/> setUnSelectedTextColor(int)
     <attr name="textSize" format="dimension"/> setTextSize(int)
     <attr name="selectionAnimationDuration" format="integer"/>
     <attr name="focusedBackgroundColor" format="color"/>
     <attr name="textHorizontalPadding" format="dimension"/> setTextHorizontalPadding(int)
     <attr name="textVerticalPadding" format="dimension"/> setTextVerticalPadding(int)
     <attr name="segmentVerticalMargin" format="dimension"/> setSegmentVerticalMargin(int)
     <attr name="segmentHorizontalMargin" format="dimension"/> setSegmentHorizontalMargin(int)
     <attr name="radius" format="dimension"/> setRadius(int)
     <attr name="topLeftRadius" format="dimension"/> setTopLeftRadius(int)
     <attr name="topRightRadius" format="dimension"/> setTopRightRadius(int)
     <attr name="bottomRightRadius" format="dimension"/> setBottomRightRadius(int)
     <attr name="bottomLeftRadius" format="dimension"/> setBottomLeftRadius(int)
     <attr name="radiusForEverySegment" format="boolean"/> setRadiusForEverySegment(boolean)
     <attr name="fontAssetPath" format="string"/>  setTypeFace(TypeFace)

Note: After every configuration change call segmentedControl.notifyConfigIsChanged() method

Example

        segmentedControl.setStrokeWidth(width.intValue());
        segmentedControl.setColumnCount(columnCount);
        segmentedControl.notifyConfigIsChanged();

SegmentedControl uses SegmentAdapter and SegmentViewHolder for displaying segments. There are allready exist a default implementations for SegmentAdapter (SegmentAdapterImpl) and SegmentViewHolder (SegmentViewHolderImpl), but if you want to make your custom implementation... well here is the steps

  1. Define segment_item.xml inside layouts folder

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/text_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:layout_margin="2dp"
            android:background="@color/colorPrimary"
            android:gravity="center"
            android:textColor="@color/colorAccent"
            android:textSize="14sp" />
    </LinearLayout>
  2. Create a SegmentViewHolder instance (AppSegmentViewHolder) (here I define the segment generic data type as a String)

    public class AppSegmentViewHolder extends SegmentViewHolder<String> {
        TextView textView;
    
        public AppSegmentViewHolder(@NonNull View sectionView) {
            super(sectionView);
            textView = (TextView) sectionView.findViewById(R.id.text_view);
        }
    
        @Override
        protected void onSegmentBind(String segmentData) {
            textView.setText(segmentData);
        }
    }
  3. Create a SegmentAdapter instance

    public class AppSegmentAdapter extends SegmentAdapter<String, AppSegmentViewHolder> {
    
        @NonNull
        @Override
        protected AppSegmentViewHolder onCreateViewHolder(@NonNull LayoutInflater layoutInflater, ViewGroup viewGroup, int i) {
            return new AppSegmentViewHolder(layoutInflater.inflate(R.layout.item_segment, null));
        }
    }
  4. Pass the adapter to the segmentedControl

    segmentedControl = (SegmentedControl) findViewById(R.id.segmented_control);
    segmentedControl.setAdapter(new AppSegmentAdapter());
  5. Finally add segments data.

    segmentedControl.addSegments(getResources().getStringArray(R.array.segments));

That's it :)

For custom implementation use SegmentedControlUtils helper class in order to define segment background type and background radius.

View Robert Apikyan profile on LinkedIn

License

Copyright 2017 Robert Apikyan

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Android Studio Internal error?

    Android Studio Internal error?

    Hello. I would like to thank you for this library, it brings a missing functionality of the platform and its very easy to use!

    I've noticed today that when I was trying to add an OnSegmentClickListener my Android Studio is throwing an internal error you can see here.

    I've also tried updating the library to the latest version. This code was working perfectly fine two days ago, and I don't know if this is the libraries fault or Andorid Studio's... Ι've updated to the latest kotlin but it was working after the update as well. Do you have any idea what could cause this? I tried cleaning my project, invalidating caches, etc, but the error is still there. Any help is greatly appreciated

    opened by lpbas 8
  • Custom Adapter

    Custom Adapter

    again, thank you for your work so far.

    I have a question regarding implementing Custom adapter, I assume that the Type of adapter can be anything, so in case i made the type as a custom model, which have icon and text, and need to implement the adapter to have icon and text, in the onSegmentBind how can I know if this is the selected or not?

    is it even possible to implement it like that, below is my implementation for the custom ViewHolder

    public class AppSegmentedViewHolder extends SegmentViewHolder<SegmentedTypeModel> {
        TextView tvTitle;
        ImageView ivIcon;
    
        public AppSegmentedViewHolder(@NonNull View sectionView) {
            super(sectionView);
            tvTitle = sectionView.findViewById(R.id.tvTitle);
            ivIcon = sectionView.findViewById(R.id.ivIcon);
    
        }
    
        @Override
        protected void onSegmentBind(SegmentedTypeModel segmentedTypeModel) {
            tvTitle.setText(segmentedTypeModel.getTitle());
            ivIcon.setImageResource(segmentedTypeModel.getIcon());
        }
    }
    
    opened by alaa7731 7
  • Segmentedcontrol not work in AndroidStudio 3.4

    Segmentedcontrol not work in AndroidStudio 3.4

    Today, I update my android studio from 3.3 to 3.4. In 3.3 version my application is working fine but at the same time, I am facing an issue.

    Error: cannot access ComponentFrameLayout class file for view_component.lib_android.com.view_component.base_view.layouts.ComponentFrameLayout not found

    I am not able to hide segmentedcontrol

    error: cannot find symbol method setVisibility(int)

    My Code :

    <segmented_control.widget.custom.android.com.segmentedcontrol.SegmentedControl android:id="@+id/rchtype_control" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="@dimen/_10sdp" app:columnCount="2" app:distributeEvenly="true" app:radius="@dimen/_12sdp" app:segments="@array/RchType" app:textVerticalPadding="@dimen/_6sdp" />

    rchType = (SegmentedControl) findViewById(R.id.rchtype_control);

    rchType.setVisibility(View.GONE); - Error show here

    opened by varshilshah29 6
  • Disable the segmented control

    Disable the segmented control

    I disabled the segment by setEnable(false) but it doesn't work So I used the following code but it is better to make disable feature

        private void disableEnableControls(boolean enable, ViewGroup vg) {
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                child.setEnabled(enable);
                if (child instanceof ViewGroup) {
                    disableEnableControls(enable, (ViewGroup) child);
                }
            }
        }
    
    opened by amrboxit4me 6
  • No way to remove segment click listeners

    No way to remove segment click listeners

    I am using this control in a cell in a recycler view for use in a form. There are duplicated calls occurring since the listener is added and never removed. I will create a pull request.

    opened by ka05 4
  • Flip segment text

    Flip segment text

    I can't find a method to change segment text so I made a custom adapter and I override this method

    @Override
        public void onSegmentSelected(boolean isSelected, boolean isReselected) {
            super.onSegmentSelected(isSelected, isReselected);
            if (isSelected) {
                setSectionDecorationSelected(true);
                itemTV.setText(R.string.on);
            } else {
                setSectionDecorationSelected(false);
                itemTV.setText(R.string.off);
            }
        }
    

    then I used this adapter in my activity by this code segmentedShipSwitch.setAdapter(new ShipSegmentAdapter()); but segment text not fliped

    opened by amrboxit4me 4
  • got error failed to resolve :com.android.support:appcompat-v7:27.1.1

    got error failed to resolve :com.android.support:appcompat-v7:27.1.1

    when I add library to dependencies I got "failed to resolve :com.android.support:appcompat-v7:27.1.1" error. my android compileSdkVersion is 25 buildToolsVersion is "25.0.3"

    opened by Atepheh 3
  • No stroke lines and background when using custom layout instead of default one

    No stroke lines and background when using custom layout instead of default one

    Hi, I am trying to create SegmentedControl that will show images instead of text.

    This is expert from xml layout:

        <segmented_control.widget.custom.android.com.segmentedcontrol.SegmentedControl
                android:id="@+id/segmented_sports"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                app:columnCount="5"
                app:distributeEvenly="true"
                app:radius="3dp"
                app:selectedBackgroundColor="@color/colorPrimary"
                app:selectedStrokeColor="@color/colorPrimary"
                app:unSelectedBackgroundColor="@color/white"
                app:unSelectedStrokeColor="@color/colorPrimary"
                app:strokeWidth="1dp"
                app:radiusForEverySegment="true"
            />
    

    This is xml layout of segment item:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            xmlns:tools="http://schemas.android.com/tools"
            tools:background="@color/white">
    
        <ImageView
                android:id="@+id/image_sport_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
            android:layout_gravity="center"
            tools:src="@drawable/sport_athletics"
            />
    </FrameLayout>
    

    These are definitions of adapter and viewholder:

    class AppSegmentAdapter : SegmentAdapter<Long, LiveEventSegmentViewHolder>() {
    
        override fun onCreateViewHolder(
            layoutInflater: LayoutInflater,
            viewGroup: ViewGroup,
            i: Int
        ): LiveEventSegmentViewHolder {
            return LiveEventSegmentViewHolder(layoutInflater.inflate(R.layout.custom_live_events_segment_item, null))
        }
    }
    
    class LiveEventSegmentViewHolder(override  val containerView: View) : SegmentViewHolder<Long>(containerView), LayoutContainer {
    
        override fun onSegmentBind(segmentData: Long?) {
            image_sport_icon.setImageDrawable(ContextCompat.getDrawable(image_sport_icon.context, SportHandler.getIconBySport(segmentData ?: 0L)))
        }
    
        override fun onSegmentSelected(isSelected: Boolean, isReselected: Boolean) {
            super.onSegmentSelected(isSelected, isReselected)
            Toast.makeText(image_sport_icon.context, "isSelected: $isSelected, isReselected: $isReselected", Toast.LENGTH_SHORT).show()
        }
    }
    

    This is When I start the app, my icons are shown but stroke lines and backgrounds are missing.

    It looks something like this:

    Screen Shot 2019-09-12 at 9 29 03 PM

    And this is how I initialize this control in fragment:

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            val sports: Array<Long> = arrayOf(SportHandler.FOOTBALL, SportHandler.BASKETBALL, SportHandler.HANDBALL, SportHandler.OTHER)
            segmented_sports.setAdapter(AppSegmentAdapter())
            (segmented_sports as SegmentedControl<Long>).addSegments(sports)
            segmented_sports.notifyConfigIsChanged()
        }
    

    What am I doing wrong here?

    opened by draskosaric 2
  • Can't send list from Kotlin code to addSegments() method

    Can't send list from Kotlin code to addSegments() method

    Hi,

    this is my segment_item.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
                  android:orientation="vertical"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                 >
        <ImageView
                android:id="@+id/segmented_image"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_gravity="center"
        />
    </FrameLayout>
    

    These are SegmentAdapter and SegmentViewHolder :

        class LiveSportsSegmentAdapter : SegmentAdapter<Long, LiveSportsSegmentAdapter.LiveSportsSegmentViewHolder>() {
            override fun onCreateViewHolder(
                layoutInflater: LayoutInflater,
                parent: ViewGroup?,
                viewType: Int
            ): LiveSportsSegmentViewHolder {
                return LiveSportsSegmentViewHolder(layoutInflater.inflate(R.layout.segment_item, null))
            }
    
            class LiveSportsSegmentViewHolder(segmentView: View) : SegmentViewHolder<Long>(segmentView), LayoutContainer {
                override val containerView: View?
                init {
                    containerView = segmentView
                }
                override fun onSegmentBind(segmentData: Long?) {
                    segmented_image.setImageDrawable(ContextCompat.getDrawable(segmented_image.context, SportHandler.getIconBySport(segmentData ?: 0)))
                }
            }
        }
    

    In Fragment I tried to set segmentedControl this way:

    override fun onActivityCreated(savedInstanceState: Bundle?) {
            super.onActivityCreated(savedInstanceState)
            top_matches_segmented.setAdapter(LiveSportsSegmentAdapter())
            val list: List<Long> = listOf(SportHandler.AMERICAN_FOOTBALL, SportHandler.FOOTBALL)
    
            (top_matches_segmented as SegmentedControl).addSegments( list )
    
    
        }
    

    For last line I get this error:

    None of the following functions can be called with the arguments supplied: public open fun addSegments(p0: (Nothing..Array<out Nothing!>?)): Unit defined in xxx.SegmentedControl public open fun addSegments(p0: (Nothing..List<Nothing!>?)): Unit defined in xxx.SegmentedControl

    How should I send those parameters to addSegments() method?

    Thanks!

    opened by draskosaric 2
  • Gradle error

    Gradle error

    After updating the gradle wrapper to the latest version (gradle-5.1.1-all), I got these errors:

    error: cannot access SectionLayout public final class SegmentViewHolder extends segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentViewHolder<java.lang.String> { ^ class file for section_layout.widget.custom.android.com.sectionlayout.SectionLayout not found

    e: java.lang.IllegalStateException: failed to analyze: java.lang.AssertionError: annotation tree hasn't been attributed yet: @kotlin.Metadata ...

    I'am using Kotlin.

    opened by hivian 2
  • No selectedStrokeColor

    No selectedStrokeColor

    Hi Robert. Great work.

    I have a small problem with segment control.

    I have the following on XML <segmented_control.widget.custom.android.com.segmentedcontrol.SegmentedControl android:id="@+id/segmented_control" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/data_package" android:layout_margin="@dimen/small_margin" app:columnCount="3" app:distributeEvenly="true" app:radius="12dp" app:strokeWidth="2dp" app:focusedBackgroundColor="@color/pb_bg_color" app:selectedBackgroundColor="@color/pb_bg_color" app:selectedStrokeColor="@color/white" app:selectedTextColor="@color/white" app:textVerticalPadding="6dp" app:unSelectedStrokeColor="@color/white_disabled" app:unSelectedTextColor="@color/white_disabled" />

    and this from Kotlin:

    segmented_control.removeAllSegments() val items = mutableListOf<String>() (segmented_control as SegmentedControl<String>).addSegments(items)

    segmented_control.setSelectedSegment(AppPreferences.lastPositionSegment) if (!update) { showDates(AppPreferences.lastPositionSegment) }

    segmented_control.addOnSegmentClickListener { val position = it.absolutePosition AppPreferences.lastPositionSegment = it.absolutePosition showDates(position) }

    But still getting a collorAccent stroke line when is selected a button, even when i defined on XML to use white color app:selectedStrokeColor="@color/white"

    opened by CubanJaco 2
  • unselect segment item by clicking doesn't works

    unselect segment item by clicking doesn't works

    There is a config method "setReselectionEnabled". I think this method is used to toggle each segment item's check/uncheck status by clicking on the segment item But it doesn't work

    opened by raiarainne 1
  • Stroke width doubles for strokes between segments

    Stroke width doubles for strokes between segments

    When I set a stroke width of 8, the areas where segments meet doubles that (due to each segment having their own stroke).

    When a segment meets another, only one of the two segments should draw a stroke.

    Example with strokeWidth set to 4dp: image

    opened by nathan-fiscaletti 0
  • how to align segment item?

    how to align segment item?

    스크린샷 2019-07-09 오후 3 40 57

    I want to align the data 11 to the left. how to align?

    [Segment item xml]

    <RelativeLayout
            android:layout_width="65dp"
            android:layout_height="65dp">
    
        <com.aby.lib.widget.CircleImageView
                android:id="@+id/civ_fuel_image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:border_color="@color/color_ff4d4d4d"
                app:border_width="1dp"
                android:layout_centerInParent="true"
                android:src="@android:color/white"/>
    
        <TextView
                android:id="@+id/tv_fuel_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:gravity="center"
                android:textColor="@color/color_ff4d4d4d"
                android:textSize="14sp"
                android:text="@string/dummy"/>
    
    </RelativeLayout>
    

    [Adapter class]

    public class ColorSegmentAdapter extends SegmentAdapter<ColorSegmentAdapter.SegmentColor, ColorSegmentAdapter.ColorSegmentVH> {
    
        private Context mContext;
    
        public ColorSegmentAdapter(Context context) {
            this.mContext = context;
        }
    
        @NonNull
        @Override
        protected ColorSegmentVH onCreateViewHolder(@NonNull LayoutInflater layoutInflater, ViewGroup parent, int viewType) {
            return new ColorSegmentVH(LayoutInflater.from(mContext).inflate(R.layout.circle_text_segment, parent, false));
        }
    
        class ColorSegmentVH extends SegmentViewHolder<SegmentColor> {
    
            @BindView(R.id.civ_fuel_image)
            CircleImageView civFuelImage;
    
            @BindView(R.id.tv_fuel_text)
            TextView tvFuelText;
    
            @BindView(R.id.rl_check_icon)
            RelativeLayout rlCheckIcon;
    
            View mRootView;
    
            public ColorSegmentVH(@NonNull View sectionView) {
                super(sectionView);
                ButterKnife.bind(this, sectionView);
                civFuelImage.setBorderWidth(8);
                mRootView = sectionView;
            }
    
            @Override
            protected void onSegmentBind(SegmentColor segmentData) {
                if (segmentData.getTitle().equals("")) {
                    mRootView.setVisibility(View.INVISIBLE);
                    mRootView.setSelected(false);
                }
                else {
                    civFuelImage.setImageResource(segmentData.getBackgroundColor());
                    civFuelImage.setBorderColor(mContext.getResources().getColor(segmentData.getUnSelectBorderColor(), null));
                    tvFuelText.setText(segmentData.getTitle());
                    tvFuelText.setTextColor(mContext.getResources().getColor(segmentData.getTitleColor(), null));
                }
            }
    
            @Override
            public void onSegmentSelected(boolean isSelected, boolean isReselected) {
                super.onSegmentSelected(isSelected, isReselected);
                if (isSelected || isReselected) {
                    civFuelImage.setBorderColor(mContext.getResources().getColor(getSegmentData().getSelectBorderColor(), null));
                    rlCheckIcon.setVisibility(View.VISIBLE);
                }
                else {
                    civFuelImage.setBorderColor(mContext.getResources().getColor(getSegmentData().getUnSelectBorderColor(), null));
                    rlCheckIcon.setVisibility(View.INVISIBLE);
                }
            }
        }
    
        public static class SegmentColor {
            private int backgroundColor;
            private int unSelectBorderColor;
            private int selectBorderColor;
            private int titleColor;
            private String title;
    
            public SegmentColor(int backgroundColor, int unSelectBorderColor, int titleColor, String title) {
                this(backgroundColor, R.color.colorPrimary, unSelectBorderColor, titleColor, title);
            }
    
            public SegmentColor(int backgroundColor, int selectBorderColor, int unSelectBorderColor, int titleColor, String title) {
                this.backgroundColor = backgroundColor;
                this.selectBorderColor = selectBorderColor;
                this.unSelectBorderColor = unSelectBorderColor;
                this.titleColor = titleColor;
                this.title = title;
            }
    
            public int getBackgroundColor() {
                return backgroundColor;
            }
    
            public void setBackgroundColor(int backgroundColor) {
                this.backgroundColor = backgroundColor;
            }
    
            public String getTitle() {
                return title;
            }
    
            public void setTitle(String title) {
                this.title = title;
            }
    
            public int getBorderColor() {
                return unSelectBorderColor;
            }
    
            public void setBorderColor(int borderColor) {
                this.unSelectBorderColor = borderColor;
            }
    
            public int getUnSelectBorderColor() {
                return unSelectBorderColor;
            }
    
            public void setUnSelectBorderColor(int unSelectBorderColor) {
                this.unSelectBorderColor = unSelectBorderColor;
            }
    
            public int getSelectBorderColor() {
                return selectBorderColor;
            }
    
            public void setSelectBorderColor(int selectBorderColor) {
                this.selectBorderColor = selectBorderColor;
            }
    
            public int getTitleColor() {
                return titleColor;
            }
    
            public void setTitleColor(int titleColor) {
                this.titleColor = titleColor;
            }
        }
    
    }
    

    [color setting]

    segColorControl.setAdapter(colorSegmentAdapter);
    
    segmentColors.add(new ColorSegmentAdapter.SegmentColor(android.R.color.white, R.color.color_ff9b9b9b, android.R.color.black, "1"));
            segmentColors.add(new ColorSegmentAdapter.SegmentColor(R.color.color_F9F7EA, android.R.color.white, android.R.color.black, "2"));
            segmentColors.add(new ColorSegmentAdapter.SegmentColor(R.color.color_A9A9A9, android.R.color.white, android.R.color.black, "3"));
            segmentColors.add(new ColorSegmentAdapter.SegmentColor(android.R.color.black, android.R.color.white, android.R.color.white, "4"));
            segmentColors.add(new ColorSegmentAdapter.SegmentColor(R.color.color_FF2600, android.R.color.white, android.R.color.white, "5"));
            segmentColors.add(new ColorSegmentAdapter.SegmentColor(R.color.color_945200, android.R.color.white, android.R.color.white, "6"));
            segmentColors.add(new ColorSegmentAdapter.SegmentColor(R.color.color_FFFB00, android.R.color.white, android.R.color.black, "7"));
            segmentColors.add(new ColorSegmentAdapter.SegmentColor(R.color.color_0433FF, android.R.color.white, android.R.color.white, "8"));
            segmentColors.add(new ColorSegmentAdapter.SegmentColor(R.color.color_008F00, android.R.color.white, android.R.color.white, "9"));
            segmentColors.add(new ColorSegmentAdapter.SegmentColor(R.color.color_942193, android.R.color.white, android.R.color.white, "10"));
            segmentColors.add(new ColorSegmentAdapter.SegmentColor(android.R.color.white, R.color.color_ff9b9b9b, android.R.color.black, "11"));
    
    segColorControl.addSegments(segmentColors);
            segColorControl.notifyConfigIsChanged();
    

    [SegmentedControl]

    <segmented_control.widget.custom.android.com.segmentedcontrol.SegmentedControl
                            android:id="@+id/seg_color_control"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginTop="15dp"
                            app:columnCount="5"/>
    
    opened by YKW93 3
Releases(1.2.0)
  • 1.2.0(Jun 25, 2019)

    1. supportedSegmentsCount - Will enabled multy selection, default value is 1, only one item can be selected at the time, if the selection count is reached the elder selection will be unselected

    2. reselectionEnabled - true each section width with will be equal to each other, false each section width will be measured depending on its content width

    Source code(tar.gz)
    Source code(zip)
  • 1.2.0.1-alpha(Jun 20, 2019)

    implementation 'com.github.RobertApikyan:SegmentedControl:1.2.0.1-alpha'

    Fixed

    java.util.NoSuchElementException at java.util.LinkedList.getLast(LinkedList.java:257) W/System.err: at segmented_control.widget.custom.android.com.segmentedcontrol.SegmentedControlControllerComponent.getLastSelectedViewHolder(SegmentedControlControllerComponent.java:103) W/System.err: at segmented_control.widget.custom.android.com.segmentedcontrol.SegmentedControlControllerComponent.recreate(SegmentedControlControllerComponent.java:201) W/System.err: at segmented_control.widget.custom.android.com.segmentedcontrol.SegmentedControlControllerComponent.notifyConfigIsChanged(SegmentedControlControllerComponent.java:156) W/System.err: at segmented_control.widget.custom.android.com.segmentedcontrol.SegmentedControl.notifyConfigIsChanged(SegmentedControl.java:620)

    Source code(tar.gz)
    Source code(zip)
  • 1.2-alpha(Jun 19, 2019)

  • 1.0.8(Nov 18, 2018)

    Two features are added.

    • First one is for background color animation while selection. Animation duration can be changed with selectionAnimationDuration attribute from xml (or programmaticallysetSelectionAnimationDuration(int duration))
    • Second one is for focused background color, which default value is selected background color with 16% of alpha. Default value can be changed with focusedBackgroundColor attribute from xml (or programmatically setFocusedBackgroundColor(int color))
    Source code(tar.gz)
    Source code(zip)
  • 1.0.5.0(Sep 12, 2018)

  • develop_1.0.3(Aug 21, 2018)

  • release_1.0.2(Mar 28, 2018)

  • release_1.0.1(Jan 28, 2018)

  • release_1.0(Sep 19, 2017)

    Android SegmentedControl + multi row support

    ##(API 16+)

    N|Solid

    Demo App, Play store link

    Or try demo App online !

    License

    Segmented control for android, with a lot of customization properties

    ScreenShots

    Download

    Add to project level build.gradle

        allprojects {
    		repositories {
    			...
    			maven { url 'https://jitpack.io' }
    		}
    	}
    

    Add dependency to app module level build.gradle

        dependencies {
    	        compile 'com.github.RobertApikyan:SegmentedControl:release_1.0'
    	}
    

    Done.

    Simple usage in XML

    <segmented_control.widget.custom.android.com.segmentedcontrol.SegmentedControl
                    android:id="@+id/segmented_control"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_margin="8dp"
                    app:columnCount="3"
                    app:distributeEvenly="true"
                    app:textVerticalPadding="6dp"
                    app:radius="12dp"
                    app:segments="@array/your_array_data" />
    

    Attributes

         <attr name="distributeEvenly" format="boolean" /> setDistributeEvenly(boolean)
         <attr name="columnCount" format="integer" /> setColumnCount(int)
         <attr name="segments" format="reference" /> addSegments(Object[]), addSegments(List)
         <attr name="selectedStockColor" format="color" /> setSelectedStockColor(int)
         <attr name="unSelectedStockColor" format="color" /> setUnSelectedStockColor(int)
         <attr name="stockWidth" format="dimension" / setStockWidth(int)
         <attr name="selectedBackgroundColor" format="color" /> setSelectedBackgroundColor(int)
         <attr name="unSelectedBackgroundColor" format="color" /> setUnSelectedBackgroundColor(int)
         <attr name="selectedTextColor" format="color"/> setSelectedTextColor(int)
         <attr name="unSelectedTextColor" format="color"/> setUnSelectedTextColor(int)
         <attr name="textSize" format="dimension"/> setTextSize(int)
         <attr name="textHorizontalPadding" format="dimension"/> setTextHorizontalPadding(int)
         <attr name="textVerticalPadding" format="dimension"/> setTextVerticalPadding(int)
         <attr name="segmentVerticalMargin" format="dimension"/> setSegmentVerticalMargin(int)
         <attr name="segmentHorizontalMargin" format="dimension"/> setSegmentHorizontalMargin(int)
         <attr name="radius" format="dimension"/> setRadius(int)
         <attr name="topLeftRadius" format="dimension"/> setTopLeftRadius(int)
         <attr name="topRightRadius" format="dimension"/> setTopRightRadius(int)
         <attr name="bottomRightRadius" format="dimension"/> setBottomRightRadius(int)
         <attr name="bottomLeftRadius" format="dimension"/> setBottomLeftRadius(int)
         <attr name="radiusForEverySegment" format="boolean"/> setRadiusForEverySegment(boolean)
    

    Note: After every configuration change call segmentedControl.notifyConfigIsChanged() method

    Example.

            segmentedControl.setStockWidth(width.intValue());
            segmentedControl.setColumnCount(columnCount);
            segmentedControl.notifyConfigIsChanged();
    

    SegmentedControl uses SegmentAdapter and SegmentViewHolder for displaying segments. There are allready exist a default implementations for SegmentAdapter (SegmentAdapterImpl) and SegmentViewHolder (SegmentViewHolderImpl), but if you want to make your custom implementation... well here is the steps

    1. define segment_item.xml inside layouts folder

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <TextView
                android:id="@+id/text_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                android:layout_margin="2dp"
                android:background="@color/colorPrimary"
                android:gravity="center"
                android:textColor="@color/colorAccent"
                android:textSize="14sp" />
        </LinearLayout>
    

    2. Craete SegmentViewHolder instance AppSegmentViewHolder (here I define the segment generic data type as a String)

        public class AppSegmentViewHolder extends SegmentViewHolder<String> {
            TextView textView;
        
            public AppSegmentViewHolder(@NonNull View sectionView) {
                super(sectionView);
                textView = (TextView) sectionView.findViewById(R.id.text_view);
            }
    
            @Override
            protected void onSegmentBind(String segmentData) {
                textView.setText(segmentData);
            }
        }
    

    3. Create SegmentAdapter instance

        public class AppSegmentAdapter extends SegmentAdapter<String, AppSegmentViewHolder> {
    
            @NonNull
            @Override
            protected AppSegmentViewHolder onCreateViewHolder(@NonNull LayoutInflater layoutInflater, ViewGroup viewGroup, int i) {
                return new AppSegmentViewHolder(layoutInflater.inflate(R.layout.item_segment, null));
            }
        }
    

    4. Pass the adapter to the segmentedControl

        segmentedControl = (SegmentedControl) findViewById(R.id.segmented_control);
        segmentedControl.setAdapter(new AppSegmentAdapter());
    

    5.Finally add segements data.

        segmentedControl.addSegments(getResources().getStringArray(R.array.segments));
    

    Thatas it )

    For custom implementation use SegmentedControlUtils helper class in order to define segment background type and background radius.

    View Robert Apikyan profile on LinkedIn

    License

    Copyright 2017 Robert Apikyan
    
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    
       http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    
    Source code(tar.gz)
    Source code(zip)
Owner
Robert
Robert
Multi Roots TreeView implementation for Android Platform with a lot of options and customization

Multi roots TreeView :palm_tree: implementation for Android Platform with a lot of options and customization

Amr Hesham 112 Jan 3, 2023
A simple library to add Emoji support to your Android Application

Emoji A library to add Emoji support to your Android app. Emojis can be picked in a PopupWindow. In order to edit and display text with Emojis this li

Niklas Baudy 1.4k Jan 4, 2023
Android library providing bread crumbs to the support library fragments.

Hansel And Gretel Android library providing bread crumbs for compatibility fragments. Usage For a working implementation of this project see the sampl

Jake Wharton 163 Nov 25, 2022
This is a picker view for android , support linkage effect, timepicker and optionspicker.(时间选择器、省市区三级联动)

Android-PickerView English Document 注意事项、详请使用方式、更新日志等,请查看 Wiki文档 Wiki文档,Wiki文档,Wiki文档 !~ 重要的事情说三遍 对于使用上有任何疑问或优化建议等,欢迎加入QQ群讨论交流技术问题。 交流群1: 387051294(推荐

Bigkoo 13.2k Jan 6, 2023
Extend From VLayout, and it will support Android X

XVLayout Extend From VLayout, and it will support Android X 从VLayout库克隆,支持Android X的RecyclerView 详细使用说明,参考:https://github.com/alibaba/vlayout Main Fea

null 1 Dec 8, 2021
Have a look at Job Allocation app build with SQLite database and Kotlin support

Job Allocation Overview Do you remember or forget sometimes to whom you allocated a task ?? Have a look at Job Allocation app build with SQLite databa

null 0 Dec 13, 2021
Android library used to create an awesome Android UI based on a draggable element similar to the last YouTube graphic component.

Draggable Panel DEPRECATED. This project is not maintained anymore. Draggable Panel is an Android library created to build a draggable user interface

Pedro Vicente Gómez Sánchez 3k Dec 6, 2022
TourGuide is an Android library that aims to provide an easy way to add pointers with animations over a desired Android View

TourGuide TourGuide is an Android library. It lets you add pointer, overlay and tooltip easily, guiding users on how to use your app. Refer to the exa

Tan Jun Rong 2.6k Jan 5, 2023
Bubbles for Android is an Android library to provide chat heads capabilities on your apps. With a fast way to integrate with your development.

Bubbles for Android Bubbles for Android is an Android library to provide chat heads capabilities on your apps. With a fast way to integrate with your

Txus Ballesteros 1.5k Jan 2, 2023
View that imitates Ripple Effect on click which was introduced in Android L (for Android 2.3+)

RippleView View that imitates Ripple Effect on click which was introduced in Android L. Usage For a working implementation, Have a look at the Sample

Muthuramakrishnan Viswanathan 1.2k Dec 30, 2022
A new canvas drawing library for Android. Aims to be the Fabric.js for Android. Supports text, images, and hand/stylus drawing input. The library has a website and API docs, check it out

FabricView - A new canvas drawing library for Android. The library was born as part of a project in SD Hacks (www.sdhacks.io) on October 3rd. It is cu

Antwan Gaggi 1k Dec 13, 2022
MarkdownView is an Android webview with the capablity of loading Markdown text or file and display it as HTML, it uses MarkdownJ and extends Android webview.

About MarkdownView (Markdown For Android) is an Android library that helps you display Markdown text or files (local/remote) as formatted HTML, and st

Feras Alnatsheh 1k Dec 20, 2022
SwipeBack for Android Activities to do pretty the same as the android "back-button" will do, but in a really intuitive way by using a swipe gesture

SwipeBack SwipeBack is for Android Activities to do pretty the same as the android "back-button" will do, but in a really intuitive way by using a swi

Hannes Dorfmann 697 Dec 14, 2022
A backport of the SwitchPreference component that was introduced on Android 4 (ICS / level 14). This port works on Android 2.1+ (Eclair MR1 / level 7).

Android Switch Preference Backport A backport of the SwitchPreference component that was introduced on Android 4 (ICS / level 14). This port works on

Benoit Lubek 498 Dec 29, 2022
Wizard Pager is a library that provides an example implementation of a Wizard UI on Android, it's based of Roman Nurik's wizard pager (https://github.com/romannurik/android-wizardpager)

Wizard Pager Wizard Pager is a library that provides an example implementation of a Wizard UI on Android, it's based of Roman Nurik's wizard pager (ht

Julián Suárez 520 Nov 11, 2022
Make your native android Toasts Fancy. A library that takes the standard Android toast to the next level with a variety of styling options. Style your toast from code.

FancyToast-Android Prerequisites Add this in your root build.gradle file (not your module build.gradle file): allprojects { repositories { ... ma

Shashank Singhal 1.2k Dec 26, 2022
Make your native android Dialog Fancy. A library that takes the standard Android Dialog to the next level with a variety of styling options. Style your dialog from code.

FancyAlertDialog-Android Prerequisites Add this in your root build.gradle file (not your module build.gradle file): allprojects { repositories { ..

Shashank Singhal 350 Dec 9, 2022
Xamarin.Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#

Xamarin.Android Xamarin.Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#. Build Status Platform

Xamarin 1.8k Jan 5, 2023