I am adding the border around tabs as shown in the second image.
I am able to add the borders on top and the bottom as shown in first image but not able to add the border on left/right side of each tab individually.
main_activity.xml
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#drawable/tab_border"
android:theme="#style/AppTheme.ActionBar"
android:visibility="invisible"
app:tabIndicatorColor="#color/colorPrimary">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="50dp"
app:layout_constraintTop_toTopOf="parent" />
#drawable/tab_border.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#efefef"/>
<stroke android:width="2dp" android:color="#c0c6cc"/>
<corners android:radius="0dp" />
<padding android:left="10dp" android:top="5dp"
android:right="10dp" android:bottom="5dp" />
</shape>
I am adding the tabs programmatically in activity class as i have to decide the no of tabs on run-time.
Using CustomTabLayout:
public class CustomTabLayout extends TabLayout {
public CustomTabLayout(Context context) {
this(context, null);
}
public CustomTabLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
#Override
public void setupWithViewPager(#Nullable ViewPager viewPager) {
super.setupWithViewPager(viewPager);
initCustomTab();
}
#SuppressWarnings({ "ConstantConditions" })
private void initCustomTab() {
int totalTab = getTabCount();
for (int i = 0; i < totalTab; i++) {
Tab tab = getTabAt(i);
if (tab == null) continue;
View view = LayoutInflater.from(getContext())
.inflate(R.layout.item_custom_tab, this, false);
tab.setCustomView(view);
}
}
}
item_custom_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="#dimen/dp_48"
android:background="#drawable/tab_border"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
</RelativeLayout>
hope this helps
Related
I am wondering if it is possible in android studio to display text following a circular shape.
NORMAL RESULT
FINAL RESULT
layout:
<LinearLayout
android:id="#+id/layout2"
android:layout_width="260dp"
android:layout_height="250dp"
android:background="#drawable/shape"
android:textColor="#ffffff"
android:gravity="center_vertical|center_horizontal"
android:layout_alignParentRight="true"
android:layout_centerVertical="true">
<TextView
android:background="#drawable/shape"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Text"/>
</LinearLayout>
AND shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<corners
android:radius="130dp"
android:bottomRightRadius="0dp"
android:topRightRadius="0dp"
/>
<solid
android:color="#color/colorPrimary5"
/>
<padding
android:left="8dp"
android:top="0dp"
android:right="8dp"
android:bottom="0dp"
/>
Try this
activity_main
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
<TextView
android:id="#+id/num_txt"
android:layout_width="185dp"
android:layout_height="185dp"
android:layout_alignParentTop="true"
android:layout_marginTop="163dp"
android:background="#drawable/bg_red"
android:gravity="center"
android:text="My name is NON"
android:textColor="#FFFFFF"
android:layout_marginLeft="10dp"
android:textSize="10dp" />
<TextView
android:id="#+id/TextView02"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/TextView01"
android:layout_marginRight="90dp"
android:layout_marginTop="122dp"
android:background="#drawable/bg_red"
android:gravity="center"
android:text="My name is NON"
android:textColor="#FFFFFF"
android:textSize="10dp" />
<TextView
android:id="#+id/TextView01"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_alignTop="#+id/num_txt"
android:layout_toRightOf="#+id/num_txt"
android:background="#drawable/bg_red"
android:gravity="center"
android:text="My name is NON"
android:textColor="#FFFFFF"
android:textSize="10dp" />
</RelativeLayout>
Create a X.M.L. file in file in drawable folder named as "bg_red"
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<corners android:radius="10dip"/>
<stroke android:color="#FF0000" android:width="5dip"/>
<solid android:color="#FF0000"/>
</shape>
Output
Try the following, It may be helpful.
1) CircularTextView.class:----------
Source: https://github.com/lisawray/circletextview
public class CircleTextView extends View {
private int maxLines;
private TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
private CharSequence charSequence = "";
private int[] leftIndents;
private int[] rightIndents;
private StaticLayout layout;
public CircleTextView(Context context) {
super(context);
}
public CircleTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CircleTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP) public CircleTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public int getRightIndent(int line, int width, int height) {
return getIndent(line, width, height);
}
public int getLeftIndent(int line, int width, int height) {
return getIndent(line, width, height);
}
public int getIndent(int line, int width, int height) {
int r = (int) (getSmallestDimension(width, height) / 2f);
float y = (r - line * getLineHeight());
return (int) (width / 2f - Math.sqrt((r * r) - y * y));
}
public void setTextSize(#DimenRes int dimenResId) {
textPaint.setTextSize(getPixels(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(dimenResId)));
}
int getPixels(int unit, float size) {
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
return (int) TypedValue.applyDimension(unit, size, metrics);
}
#Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
maxLines = (int) Math.floor(getSmallestDimension(w, h) / getLineHeight());
leftIndents = new int[maxLines];
rightIndents = new int[maxLines];
for (int line = 0; line < maxLines; line++) {
leftIndents[line] = getLeftIndent(line, w, h);
rightIndents[line] = getRightIndent(line, w, h);
}
makeNewLayout();
}
public void setText(CharSequence charSequence) {
this.charSequence = charSequence;
makeNewLayout();
}
private void makeNewLayout() {
StaticLayout.Builder builder = StaticLayout.Builder.obtain(charSequence, 0, charSequence.length(), textPaint, getMeasuredWidth());
builder.setIndents(leftIndents, rightIndents);
builder.setMaxLines(maxLines);
layout = builder.build();
}
#Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
layout.draw(canvas);
}
private int getSmallestDimension(int width, int height) {
return Math.min(width, height);
}
public float getLineHeight() {
return textPaint.getFontMetrics().bottom - textPaint.getFontMetrics().top;
}
public TextPaint getTextPaint() {
return textPaint;
}
}
2) MainActivity_.class:-----
public class MainActivity_ extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout7);
CircleTextView textView = (CircleTextView) findViewById(R.id.circle_text_view);
textView.setTextSize(R.dimen.txt_size); // declare txt_size in dimens (14sp for example).
textView.setText("This is aasdadadad nice test to insure the reliability of this shit fdgggh hfhjg khk kjghk lh lhlj hl hllh ; ;l hkjjl hlhl hl lhljh lhl hhlh hlh llh lhhj l llhl lh l lh lh");
}
}
3) layout7.xml:-------
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:background="#drawable/s"
android:layout_width="205dp"
android:layout_height="205dp"
android:id="#+id/frame"
android:layout_centerInParent="true"
android:gravity="center" />
<com.example.admin.accessories.CircleTextView
android:layout_width="150dp"
android:layout_height="150dp"
android:id="#+id/circle_text_view"
android:layout_centerInParent="true"
android:gravity="center">
</com.example.admin.accessories.CircleTextView>
</RelativeLayout>
4) s.xml:---------
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:innerRadius="0dp"
android:thickness="100dp"
android:useLevel="false">
<solid
android:color="#android:color/holo_red_dark"/>
</shape>
5) Output:---------
6) Note: I'm not the author of the code for the CircleTextView class. So, please click on the link above to find more detailed information about this project (bugs-enhacements...).
Here I'm trying to change the position of TabIndicator to top from bottom but not getting success. I want just like as image is showing.
I have done everything but indicator is in bottom not in top and even I can't add dividers between Tabs too. Please look at my code and help me to solve this issue.
My code is like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<com.cws.widget.MyTabLayout
android:id="#+id/mainTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
app:tabBackground="#color/drawer_tab_background"
app:tabGravity="fill"
app:tabIndicatorColor="#color/green"
app:tabMode="fixed" />
<com.cws.widget.NonSiwpablePager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
And styles.xml
<style name="AppCompatTheme" parent="Theme.AppCompat.Light.NoActionBar"></style>
<style name="AppToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:windowNoTitle">true</item>
<item name="colorPrimary">#000</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="colorControlNormal">#FFF</item>
</style>
MyTabLayout.java
public class MyTabLayout extends TabLayout {
public MyTabLayout(Context context) {
super(context);
}
public MyTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int height = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if (h > height) height = h;
}
heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
ViewPager.java
public class NonSiwpablePager extends ViewPager {
public NonSiwpablePager(Context context) {
super(context);
}
public NonSiwpablePager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return false;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
}
Firstly you need to remove that tab indicator,
app:tabIndicatorHeight="0dp"
this line add into <com.cws.widget.MyTabLayout> xml file. and after that add that http://pastie.org/private/5lsxm7l8qoay4naobuddow as background
app:tabBackground="#drawable/selector_tab"
Hope it will work for you
I use :
public class CheckableRelativeLayout extends RelativeLayout implements Checkable {
private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked, };
private boolean mChecked;
public CheckableRelativeLayout(Context context) {
super(context);
}
public CheckableRelativeLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CheckableRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void setChecked(boolean checked) {
if (mChecked != checked) {
mChecked = checked;
refreshDrawableState();
}
}
#Override
public boolean isChecked() {
return mChecked;
}
#Override
public void toggle() {
setChecked(!mChecked);
}
#Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
}
based on this and i use it like this :
<com.example.components.CheckableRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/CheckableRelativeLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/selector_background_navigation_item"
android:orientation="horizontal"
android:padding="10dp"
android:gravity="center_vertical" >
<ImageView
android:id="#+id/navigationDrawerItemImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/navigationDrawerItemTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/navigationDrawerItemImageView"
android:layout_margin="5dp"
android:layout_toRightOf="#+id/navigationDrawerItemImageView"
android:textColor="#drawable/selector_text_navigation_item"
android:textSize="#dimen/text_size_small" />
</com.example.components.CheckableRelativeLayout>
in a list item where selector_background_navigation_item defined like this :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="false" android:state_pressed="false" android:drawable="#color/darkblue"></item>
<item android:state_pressed="true" android:drawable="#color/sirinblue"></item>
<item android:state_checked="true" android:drawable="#color/white"></item>
</selector>
and selector_text_navigation_item defined like this :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="false" android:state_pressed="false" android:color="#color/white"></item>
<item android:state_pressed="true" android:color="#color/lightblue"></item>
<item android:state_checked="true" android:color="#color/lightblue"></item>
</selector>
Now, the problem is that the TextView Selector does not respond to the check events, while the CheckableRelativeLayout does, but both respond correctly to simple presses, whats the best way to fix this? maybe CheckableRelativeLayout missing some super call that handles its children checked state?
adding android:duplicateParentState="true" to the TextView did the trick!
I need a "Button" that would have a texture background, and dynamic text. The end result should be like this, but the background is a textured picture.
I tried to use a RelativeLayout with a TextView inside, but the problem is that the result CustomView does not wrap_content in width/height.
Here is the custom_buttonXML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#drawable/custom_button_selector"
android:layout_height="match_parent">
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_centerInParent="true"
/>
</RelativeLayout>
Here is the Code:
public class CustomButton extends RelativeLayout {
private LayoutInflater mInflater;
private RelativeLayout mContainer;
private TextView mTextView;
public CustomButton(Context context) {
super(context);
mInflater = LayoutInflater.from(context);
customInit(context);
}
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
mInflater = LayoutInflater.from(context);
customInit(context);
}
public CustomButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mInflater = LayoutInflater.from(context);
customInit(context);
}
private void customInit(Context ctx) {
mContainer = (RelativeLayout) mInflater.inflate(R.layout.cutom_button_view, this, true);
mTextView = (TextView) mContainer.findViewById(R.id.tv);
}
public RelativeLayout getContainer() {
return mContainer;
}
public TextView getTextView() {
return mTextView;
}
}
This is how I use it at the moment, and it works:
<com.myapp.views.CustomButton
android:id="#+id/btn"
android:layout_width="80dp"
android:layout_height="50dp"/>
But I want to use it like this (for dynamic text), and it won't work:
<com.myapp.views.CustomButton
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
It will actually stretch across the whole screen, ignoring the layout rules.
If this solution is a bad idea, could you recommend an alternative that would produce the same results?
You need to Shape file for that..
try out this.
<shape android:shape="rectangle">
<corners android:radius="56dp" />
<solid android:color="Color Whaterver You Want" />
<padding android:bottom="4dp" android:left="4dp" android:right="4dp" android:top="4dp" />
</shape>
Put this xml file under res/drawal folder.
now just in Your view pass this attribute..
android:background="#drawable/your file name"
Hop it works for you..
Custom layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/my_background">
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center" />
</RelativeLayout>
Custom layout java:
public class CustomButton extends FrameLayout {
private RelativeLayout mContainer;
private TextView mTextView;
public CustomButton(Context context) {
super(context);
customInit(context);
}
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
customInit(context);
}
public CustomButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
customInit(context);
}
private void customInit(Context ctx) {
LayoutInflater.from(ctx).inflate(R.layout.custom_button_viewa, this, true);
mContainer = (RelativeLayout) findViewById(R.id.container);
mTextView = (TextView) findViewById(R.id.tv);
}
public RelativeLayout getContainer() {
return mContainer;
}
public TextView getTextView() {
return mTextView;
}
}
Now can be used as:
<com.androidbolts.databindingsample.model.CustomButton
android:id="#+id/customButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
I have customised progressbar.
HorizontalSlider class which inherits from ProgressBar is:
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ProgressBar;
public class HorizontalSlider extends ProgressBar {
private OnProgressChangeListener listener;
private static final int padding = 2;
private static final int getMin = 11;
public interface OnProgressChangeListener {
void onProgressChanged(View v, int progress);
}
public HorizontalSlider(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, android.R.attr.progressBarStyleHorizontal);
}
public HorizontalSlider(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HorizontalSlider(Context context) {
super(context);
}
public void setOnProgressChangeListener(OnProgressChangeListener l) {
listener = l;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) {
float x_mouse = event.getX() - padding;
float width = getWidth() - 2 * padding;
int progress = Math.round((float) getMax() * (x_mouse / width));
if (progress < getMin)
progress = getMin;
if (progress > getMax())
progress = getMax();
this.setProgress(progress);
if (listener != null)
listener.onProgressChanged(this, progress);
}
return true;
}
}
UI in xml format is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="100dip"
android:gravity="center_horizontal" >
<com.astro.mania.classes.HorizontalSlider
android:id = "#+id/slider"
android:layout_width = "fill_parent"
android:layout_height= "wrap_content"
android:max="100"
android:layout_centerHorizontal="true"
style="?android:attr/progressBarStyleHorizontal" />
<com.astro.mania.classes.HorizontalSlider
android:id="#+id/progressBar"
android:progressDrawable="#drawable/progressbar"
android:layout_width="fill_parent"
android:layout_height="24dip"
style="?android:attr/progressBarStyleHorizontal"
android:indeterminateOnly="false"
android:max="100"
android:layout_below="#id/slider"
android:layout_marginTop="20dip" />
</RelativeLayout>
Progressbar customised as below:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<shape>
<gradient
android:startColor="#fffffe"
android:centerColor="#0b131e"
android:centerY="0.75"
android:endColor="#0d1522"
android:angle="270" />
</shape>
</item>
<item android:id="#android:id/secondaryProgress">
<clip>
<shape>
<gradient
android:startColor="#234"
android:centerColor="#234"
android:centerY="0.75"
android:endColor="#a24"
android:angle="270"
/>
</shape>
</clip>
</item>
<item android:id="#android:id/progress">
<bitmap android:src="#drawable/btn_slide_arrow" android:dither="true" />
</item>
</layer-list>
Finally the activity is like this:
public class LensaMania extends Activity {
private HorizontalSlider slider, slider2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.activity_lensamania);
Log.i("LensaMania", "LensaMania activity started...");
setProgressBarVisibility(true);
slider = (HorizontalSlider) this.findViewById(R.id.slider);
slider.setOnProgressChangeListener(changeListener);
slider2 = (HorizontalSlider) this.findViewById(R.id.progressBar);
slider2.setVisibility(View.VISIBLE);
slider2.setMax(100);
slider2.setProgress(11);
slider2.setOnProgressChangeListener(changeListener);
}
private OnProgressChangeListener changeListener = new OnProgressChangeListener() {
public void onProgressChanged(View v, int progress) {
setProgress(progress);
Log.i("Progress is:", "=>" + progress);
}
};
}
When I run the application and slide progreebar, the image is repeated like image below. I want to have just one image and when I slide it to left want to see just one arrow. How to ask progressbar to don't repeat the image?