I'm working on a project and I need to lock my own app with a PIN code.
I want to use four circles as background of my edittext and fill each circle when user enters a digit. Just like iOS lock screen.
How can I fill these circles when there's an input?
Here's a quick example I put together for you to get started.
You should firstly define what your ellipse's for the pass-code will look like, I've defined mine inside two files inside my drawable folder:
elipse.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<gradient android:startColor="#8BE807" android:endColor="#68B002" android:angle="270" />
</shape>
ellipse_checked.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<gradient android:startColor="#C7C7C7" android:endColor="#8A8A8A" android:angle="270"/>
</shape>
Next I have added four ellipses (View's) and an ExitText to my view like so:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:gravity="center_vertical|center_horizontal"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<View
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/ellipse"
android:id="#+id/elipse1"
android:layout_margin="10dip" />
<View
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/ellipse"
android:id="#+id/elipse2"
android:layout_margin="10dip" />
<View
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/ellipse"
android:id="#+id/elipse3"
android:layout_margin="10dip" />
<View
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/ellipse"
android:id="#+id/elipse4"
android:layout_margin="10dip" />
</LinearLayout>
<EditText
android:layout_width="100dip"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:id="#+id/txtPass"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dip"
android:textAlignment="center"
android:maxLength="4"
android:gravity="center" />
</LinearLayout>
Then inside my MainActivity I have:
int passlen = 0;
Drawable mDrawableElipseChecked;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Used to change our pass-code ellipses style
mDrawableElipseChecked = this.getResources().getDrawable(R.drawable.ellipse_checked);
// Ellipses
final View elipse1 = findViewById(R.id.elipse1);
final View elipse2 = findViewById(R.id.elipse2);
final View elipse3 = findViewById(R.id.elipse3);
final View elipse4 = findViewById(R.id.elipse4);
// Listen for text changes to our pass-code EditText
final EditText txtPass = (EditText) findViewById(R.id.txtPass);
txtPass.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (keyEvent.getAction() == KeyEvent.ACTION_UP) {
// Crude example of how to "check" / "un-check" our
// ellipses NOTE: You should write a better implementation
// for handling deletes etc
passlen = txtPass.getText().length();
if (passlen == 1) {
elipse1.setBackground(mDrawableElipseChecked);
} else if (passlen == 2)
elipse2.setBackground(mDrawableElipseChecked);
else if (passlen == 3)
elipse3.setBackground(mDrawableElipseChecked);
else if (passlen == 4)
elipse4.setBackground(mDrawableElipseChecked);
else {
return true;
}
}
return false;
}
});
}
You should now have a very simple example of how to implement pass-code like functionality to an app.
Note: This is a simple demo of how to get started implementing a pass-code like screen, you should adapt and improve this to suit your needs.
Related
I have a very simple Dialog:
On click of the button I would like to toggle visibility of the second EditText:
public class SomeDialog extends DialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.some_dialog, container, false);
EditText editSecond = root.findViewById(R.id.text_second);
Button buttonOk = root.findViewById(R.id.button_ok);
buttonOk.setOnClickListener(v -> {
editSecond.setVisibility(editSecond.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
});
return root;
}
}
I would like it to be animated smoothly, so I set "animateLayoutChanges" to "true":
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:animateLayoutChanges="true"
>
<TextView
android:id="#+id/titleText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:padding="8dp"
android:text="Title"
android:textAppearance="#style/TextAppearance.AppCompat.Large.Inverse"
android:textSize="18sp"
/>
<EditText
android:id="#+id/text_first"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="First"
/>
<EditText
android:id="#+id/text_second"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Second"
/>
<Button
android:id="#+id/button_ok"
style="#style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="8dp"
android:text="Ok"
/>
</LinearLayout>
The dialog gets animated, but unfortunately not in the correct order.
What happens:
the TextEdit vanishes
the Dialog height snaps (instantly) to the smaller height
the Button moves up (animated)
So between 2) and 3) the button is not visible and slowly slides into the (already smaller) dialog from offscreen (bottom).
What can be done about this?
(Code Sample works and can be copy/pasted into Android Studio as is)
My Client wants a diamond shaped progress that looks like this:
My first attempt was to use a library, but I can't find one that exists
My next attempt was to learn how to use the ProgressBar view that comes with android, and set my own drawable using this answer (the closest thing to an answer on stack overflow), but the answer only works on ring shapes, not rectangles.
What is the best way to create a diamond-shaped progress view? (By any means: custom view, progressDrawable) and how do I do that?
After some more tests, I came up with a hacky answer. It's just 4 progress bars aligned to the edge of a Relative layout, and a CardView on top of them. Rotate the whole thing, and wrap it in a class and bam, you got yourself a diamond progress bar. (Use math to calculate the progress of each bar)
It can be a little weird on the corners (where the progress bars overlap) but overall it works well enough
Usage:
ViewGroup background;
int count = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Something to add the progress bar to
background = (ViewGroup) findViewById(R.id.relative);
//initializing the progress bar
final DiamondProgress diamondProgress = new DiamondProgress(this);
diamondProgress.setMax(1000);
//adding the progress bar
background.addView(diamondProgress.getView());
/* Sample Code for animating the progress bar*/
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
diamondProgress.setProgress(count++);
}
});
}
}, 0, 25);
}
Code:
XML: layout/diamond_view
<?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:orientation="vertical"
android:layout_width="wrap_content"
android:rotation="45"
android:padding="43dp"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="200dp"
android:layout_height="200dp">
<RelativeLayout
android:layout_width="wrap_content"
android:rotation="90"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="8dp"
android:layout_alignParentBottom="true"
android:rotation="180">
<ProgressBar
android:layout_width="match_parent"
android:layout_height="8dp"
android:layout_marginLeft="3dp"
android:id="#+id/dp_progress4"
style="?android:attr/progressBarStyleHorizontal"
android:progressDrawable="#drawable/progress_drawable"
android:layout_alignParentBottom="true" />
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="8dp"
android:layout_alignParentBottom="true"
android:rotation="180">
<ProgressBar
android:layout_width="match_parent"
android:layout_height="8dp"
android:layout_marginLeft="3dp"
android:progress="50"
android:id="#+id/dp_progress3"
android:progressDrawable="#drawable/progress_drawable"
style="?android:attr/progressBarStyleHorizontal"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:rotation="90"
android:layout_height="match_parent">
<ProgressBar
android:layout_width="match_parent"
android:layout_height="8dp"
android:layout_marginLeft="3dp"
android:progress="100"
android:id="#+id/dp_progress2"
android:progressDrawable="#drawable/progress_drawable"
style="?android:attr/progressBarStyleHorizontal" />
</RelativeLayout>
<ProgressBar
android:layout_width="match_parent"
android:layout_height="8dp"
android:layout_marginLeft="3dp"
android:progress="100"
android:progressDrawable="#drawable/progress_drawable"
style="?android:attr/progressBarStyleHorizontal"
android:id="#+id/dp_progress1"/>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_margin="4dp"
android:id="#+id/dp_card"
android:elevation="10dp"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:rotation="-45"
android:id="#+id/dp_addView"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Sample Inside Content"
android:id="#+id/dp_text"
android:gravity="center"
android:textSize="24sp"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
</RelativeLayout>
XML: drawable/progress_drawable
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- background -->
<item android:id="#android:id/background">
<shape>
<corners android:radius="3dp"/>
<solid android:color="#f2f2f2" />
</shape>
</item>
<!-- for the actual progress bar -->
<item android:id="#android:id/progress">
<clip android:gravity="left">
<shape>
<corners android:radius="3dp"/>
<solid android:color="#color/colorAccent" />
</shape>
</clip>
</item>
</layer-list>
Java Class
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
/**
* Created by Pythogen on 9/27/2017.
*/
public class DiamondProgress {
Context context;
View view;
RelativeLayout addView;
int progress = 0;
int max = 100;
ProgressBar p1;
ProgressBar p2;
ProgressBar p3;
ProgressBar p4;
public DiamondProgress(Context context) {
this.context = context;
view = LayoutInflater.from(context).inflate(R.layout.diamond_view, null);
addView = ((RelativeLayout) view.findViewById(R.id.dp_addView));
p1 = (ProgressBar) view.findViewById(R.id.dp_progress1);
p2 = (ProgressBar) view.findViewById(R.id.dp_progress2);
p3 = (ProgressBar) view.findViewById(R.id.dp_progress3);
p4 = (ProgressBar) view.findViewById(R.id.dp_progress4);
}
public View getView() {
return view;
}
public RelativeLayout getHostOfInsideContent() {
return addView;
}
public void setProgress(int progress) {
this.progress = progress;
updateProgressBar();
}
public void setMax(int max) {
this.max = max;
p1.setMax(max);
p2.setMax(max);
p3.setMax(max);
p4.setMax(max);
}
public void updateProgressBar() {
double prog = ((double)progress)/max;
if (prog<.25) {
p1.setProgress(this.progress*4);
p2.setProgress(0);
p3.setProgress(0);
p4.setProgress(0);
} else {
p1.setProgress(max);
if (prog<.5) {
p2.setProgress((this.progress*4)-max);
p3.setProgress(0);
p4.setProgress(0);
} else {
p2.setProgress(max);
if (prog<.75) {
p3.setProgress((this.progress*4)-max*2);
p4.setProgress(0);
} else {
p3.setProgress(max);
p4.setProgress((this.progress*4)-max*3);
}
}
}
}
}
Oh, and if you plan on using this, be sure to add the CardView dependancy to your build.grade compile 'com.android.support:cardview-v7:25.1.1'
This question already has answers here:
Outlined Edit Text from Material Design
(7 answers)
Closed 4 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
I am trying to create custom TextInputLayout. How can I create below custom TextInputLayout?
You should use Material Design style for Outline Box. Just simple use:
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
in TextInputLayout. See Text Field for Android in Material Design Guide
Here is an workaround:
1. Design your layout structure as below:
activity_test.xml
<?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"
android:padding="16dp"
android:background="#android:color/white">
<!-- Username -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginTop="10dp"
android:background="#drawable/bg_rounded_input_field" />
<TextView
android:id="#+id/text_dummy_hint_username"
android:layout_width="wrap_content"
android:layout_height="2dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="16dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:text="Username"
android:textSize="16sp"
android:background="#android:color/white"
android:visibility="invisible"/>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:hint="Username"
android:textColorHint="#android:color/black"
app:hintTextAppearance="#style/HintTextStyle">
<EditText
android:id="#+id/edit_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text|textCapWords"
android:maxLines="1"
android:backgroundTint="#android:color/transparent"/>
</android.support.design.widget.TextInputLayout>
</RelativeLayout>
<!-- Password -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<View
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginTop="10dp"
android:background="#drawable/bg_rounded_input_field" />
<TextView
android:id="#+id/text_dummy_hint_password"
android:layout_width="wrap_content"
android:layout_height="2dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="16dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:text="Password"
android:textSize="16sp"
android:background="#android:color/white"
android:visibility="invisible"/>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:hint="Password"
android:textColorHint="#android:color/black"
app:hintTextAppearance="#style/HintTextStyle">
<EditText
android:id="#+id/edit_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:maxLines="1"
android:backgroundTint="#android:color/transparent"/>
</android.support.design.widget.TextInputLayout>
</RelativeLayout>
</LinearLayout>
2. Use below drawable bg_rounded_input_field.xml for rounded corners.
res/drawable/bg_rounded_input_field.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<stroke
android:color="#android:color/black"
android:width="2dp">
</stroke>
<corners
android:radius="8dp">
</corners>
</shape>
3. Use below HintTextStyle to TextInputLayout by adding attribute app:hintTextAppearance="#style/HintTextStyle".
res/values/styles.xml
<style name="HintTextStyle" parent="TextAppearance.Design.Hint">
<item name="android:textSize">16sp</item>
</style>
4. Finally, in your Activity just show/hide TextView text_dummy_hint_username and text_dummy_hint_password
during focus change.
FYI, I have used Handler with delay 100 millis to
show the dummy hints TextView to sync with TextInputLayout hint text
animation.
TestActivity.java
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class TestActivity extends AppCompatActivity {
TextView textDummyHintUsername;
TextView textDummyHintPassword;
EditText editUsername;
EditText editPassword;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
textDummyHintUsername = (TextView) findViewById(R.id.text_dummy_hint_username);
textDummyHintPassword = (TextView) findViewById(R.id.text_dummy_hint_password);
editUsername = (EditText) findViewById(R.id.edit_username);
editPassword = (EditText) findViewById(R.id.edit_password);
// Username
editUsername.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// Show white background behind floating label
textDummyHintUsername.setVisibility(View.VISIBLE);
}
}, 100);
} else {
// Required to show/hide white background behind floating label during focus change
if (editUsername.getText().length() > 0)
textDummyHintUsername.setVisibility(View.VISIBLE);
else
textDummyHintUsername.setVisibility(View.INVISIBLE);
}
}
});
// Password
editPassword.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// Show white background behind floating label
textDummyHintPassword.setVisibility(View.VISIBLE);
}
}, 100);
} else {
// Required to show/hide white background behind floating label during focus change
if (editPassword.getText().length() > 0)
textDummyHintPassword.setVisibility(View.VISIBLE);
else
textDummyHintPassword.setVisibility(View.INVISIBLE);
}
}
});
}
}
OUTPUT:
Hope this will help~
I want to implement same kind of animation such as linked in does in android application for its Introduction(Login / register) screen.
I am using view pager for Introduction screen and i want to implement fadein fadeout animation on background image change, As per swipe right to left or vice versa.
I want to implement fadein and fadeout animation on background image change according to swipe of screen.
any help is appreciated.
Please take a look at my layout code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/background_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:weightSum="7" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:gravity="right"
android:orientation="horizontal" >
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginRight="5dp"
android:src="#drawable/icon_skip" />
<TextView
android:id="#+id/skip_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Skip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/white" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4"
android:gravity="bottom"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/logo" />
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context="com.xyz.View.IntroductionScreen" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:gravity="center"
android:orientation="vertical" >
<Button
android:id="#+id/connection_bt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:background="#drawable/button"
android:text="CONNEXION"
android:textColor="#android:color/white" />
<Button
android:id="#+id/register_bt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:layout_marginTop="10dp"
android:background="#drawable/button"
android:text="INSCRIPTION"
android:textColor="#android:color/white" />
</LinearLayout>
</LinearLayout>
And View pager fragment layout is
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="#+id/text_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical" >
<TextView
android:id="#+id/tagline_tv1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:singleLine="true"
android:text="Laissez votre prochain job"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/white" />
<TextView
android:id="#+id/details_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:maxLines="2"
android:text="vous trouver"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/white" />
</LinearLayout>
</RelativeLayout>
sample Splashs creen this is what i want to implement.
Thank you
This is a lag free one and also handles the Buttons
Main Idea:
1) first create transparent background for your fragments.
2) Create LayerDrawable and add background image of each fragment as an item. Then add your LayerDrawable as a background of your viewpager.
3) in onCreate method set alpha of each layer correctly so just upper one has alpha value of 255.
4) set for each view of your FragmentStatPagerAdapter a tag that corresponds to drawable index that you declared in the LayerDrawable. for example when you open the app FragmentA is showing so its tag must correspond to upper drawable that is 2 (beginning from 0). last page tag must be 0 corresponds to lowest drawable.
5) change drawable of each view at the function transformPage
6) for adding the button use RelativeLayout.
In order to place buttons on top of all views use RelativeLayout. Later children are placing higher on the Z axis. You can see it in the code:
now lets see code:
MainActivity
public class MainActivity extends FragmentActivity {
ViewPager viewPager=null;
int numberOfViewPagerChildren = 3;
int lastIndexOfViewPagerChildren = numberOfViewPagerChildren - 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(new MyAdapter(getSupportFragmentManager()));
final LayerDrawable background = (LayerDrawable) viewPager.getBackground();
background.getDrawable(0).setAlpha(0); // this is the lowest drawable
background.getDrawable(1).setAlpha(0);
background.getDrawable(2).setAlpha(255); // this is the upper one
viewPager.setPageTransformer(true, new ViewPager.PageTransformer() {
#Override
public void transformPage(View view, float position) {
int index = (Integer) view.getTag();
Drawable currentDrawableInLayerDrawable;
currentDrawableInLayerDrawable = background.getDrawable(index);
if(position <= -1 || position >= 1) {
currentDrawableInLayerDrawable.setAlpha(0);
} else if( position == 0 ) {
currentDrawableInLayerDrawable.setAlpha(255);
} else {
currentDrawableInLayerDrawable.setAlpha((int)(255 - Math.abs(position*255)));
}
}
});
}
class MyAdapter extends FragmentStatePagerAdapter
{
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment=null;
if(i==0)
{
fragment=new FragmentA();
}
if(i==1)
{
fragment=new FragmentB();
}
if(i==2)
{
fragment=new FragmentC();
}
return fragment;
}
#Override
public int getCount() {
return numberOfViewPagerChildren;
}
#Override
public boolean isViewFromObject(View view, Object object) {
if(object instanceof FragmentA){
view.setTag(2);
}
if(object instanceof FragmentB){
view.setTag(1);
}
if(object instanceof FragmentC){
view.setTag(0);
}
return super.isViewFromObject(view, object);
}
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/layerdrawable" >
</android.support.v4.view.ViewPager>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:layout_marginBottom="48dip" >
<Button
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Sign in"
android:layout_margin="16dip"
android:background="#2ec6e4"
android:textColor="#FFFFFF" />
<Button
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Join us"
android:background="#2ec6e4"
android:layout_margin="16dip"
android:textColor="#FFFFFF"
/>
</LinearLayout>
</RelativeLayout>
LayerDrawable
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<bitmap
android:id="#+id/Idofbg3"
android:gravity="fill"
android:src="#drawable/bg3" />
</item>
<item>
<bitmap
android:id="#+id/Idofbg2"
android:gravity="fill"
android:src="#drawable/bg2" />
</item>
<item>
<bitmap
android:id="#+id/Idofbg1"
android:gravity="fill"
android:src="#drawable/bg1" />
</item>
</layer-list>
for lazy people who just do not want to declare fragments:
FragmentA
public class FragmentA extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_a,container,false);
return v;
}
}
fragment_a.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:id="#+id/FragmentA"
android:background="#android:color/transparent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="This is Fragment A"
android:textColor="#FFFFFF"
android:id="#+id/textView"
android:gravity="center"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>
Set a ViewPager.PageTransformer to the ViewPager and achieve the desired animation using aplha and translation animation properties.
The most important input is the position parameter passed to transformPage callback. The position value indicates how the view is positioned currently.
Assuming the views in ViewPager are full width, here is how position value need to be interpreted.
------------------------------------------------------------------------------------
position | what does it mean
------------------------------------------------------------------------------------
0 | view is positioned in the center and fully visible to the user.
-1 | view is positioned in the left and not visible to the user.
1 | view is positioned in the right and not visible to the user.
>-1 & <0 | view is being scrolled towards left and is partially visible.
>0 & <1 | view is being scrolled towards right and is partially visible.
------------------------------------------------------------------------------------
mPager.setPageTransformer(true, new ViewPager.PageTransformer() {
#Override
public void transformPage(View view, float position) {
// Ensures the views overlap each other.
view.setTranslationX(view.getWidth() * -position);
// Alpha property is based on the view position.
if(position <= -1.0F || position >= 1.0F) {
view.setAlpha(0.0F);
} else if( position == 0.0F ) {
view.setAlpha(1.0F);
} else { // position is between -1.0F & 0.0F OR 0.0F & 1.0F
view.setAlpha(1.0F - Math.abs(position));
}
// TextView transformation
view.findViewById(R.id.textView).setTranslationX(view.getWidth() * position);
}
});
Here is the layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_alignParentTop="true"
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView" />
</RelativeLayout>
Here is the screen record:
I have implemented expandablelistview in android app and also implemented divider in it.
I have one problem in not getting the divider between the last item of the child and next group header.
Following image is how I want :
But following is what I'm getting:
Here if you compare both images the divider between the CID and About Set is not coming how to implement that divider ?
Also the groupIndicator is not changing inspite of providing the xml in the groupindicator containing the item tag with 2 different images in android:state_expanded and android:state_empty.
But the property of android:state_expanded and android:state_empty doesn't appear.
It's very easy to Implement.
1- We will add divider in groub_item_layout and child_item_layout:
group_item_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:background="#color/white"
android:minHeight="50dp"
android:orientation="vertical">
<View
android:id="#+id/adapter_divider_top"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#B6B6B6" />
<TextView
android:id="#+id/tv_adapter_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:paddingBottom="10dp"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:text="Home"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#color/primary_text" />
</LinearLayout>
child_item_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:orientation="vertical">
<TextView
android:id="#+id/tv_adapter_desc"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:text="description"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#212121" />
<View
android:id="#+id/adapter_divider_bottom"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/divider" />
</LinearLayout>
2- In your Adapter getChildView() and getGroupView() Methods:
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View view, ViewGroup viewGroup) {
if (view == null) {
view = mInflater.inflate(R.layout.group_item_layout, null);
mGroupViewHolder = new GroupViewHolder();
mGroupViewHolder.tvTitle = (TextView) view.findViewById(R.id.tv_adapter_title);
mGroupViewHolder.dividerTop = view.findViewById(R.id.adapter_divider_top);
view.setTag(mGroupViewHolder);
} else {
mGroupViewHolder = (GroupViewHolder) view.getTag();
}
// That if you want to show divider in expanded group only.
// If you want to show divider in all group items remove this block.
if (isExpanded) {
mGroupViewHolder.dividerTop.setVisibility(View.VISIBLE);
} else {
mGroupViewHolder.dividerTop.setVisibility(View.INVISIBLE);
}
// That if you want to show divider in expanded group only.
String myTitle = getGroup(groupPosition);
if(myTitle != null) {
mGroupViewHolder.tvTitle.setText(myTitle);
}
return view;
}
#Override
public View getChildView(final int groupPosition, int childPosition, boolean isLastChild, View convertView, final ViewGroup parent) {
if (view == null) {
view = mInflater.inflate(R.layout.child_item_layout, null);
mChildViewHolder = new ChildViewHolder();
mChildViewHolder.tvDesc = (TextView) view.findViewById(R.id.tv_adapter_desc);
mChildViewHolder.dividerBottom = view.findViewById(R.id.adapter_divider_bottom);
view.setTag(mChildViewHolder);
} else {
mChildViewHolder = (ChildViewHolder) view.getTag();
}
if(isLastChild) {
mChildViewHolder.dividerBottom.setVisibility(View.VISIBLE);
} else {
mChildViewHolder.dividerBottom.setVisibility(View.INVISIBLE);
}
Timesheet timesheet = getChild(groupPosition, childPosition);
if(timesheet != null) {
mChildViewHolder.tvDesc.setText(timesheet.getDescription());
}
return view;
}
Hope this helps anyone.
Instead of using ExpandableListView's divider, you can make your own. Set the background of the lists's parent elements to
android:background="#drawable/top_divider"
Where drawable/top_divider.xml contains
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="-1dp" android:right="-1dp" android:bottom="-1dp">
<shape>
<solid android:color="#android:color/transparent" />
<stroke android:width="1dp" android:color="#android:color/black" />
</shape>
</item>
</layer-list>
Firstly make custom expandable listview...
then add different divider to header and its child
Refer the code(header of expandable listview xml):-
<?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="match_parent"
android:background="#000000" >
<ImageView
android:id="#+id/divider_top"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#drawable/divider_vertical" />
<TextView
android:id="#+id/lblListHeader"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/divider_top"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:textColor="#c5e26d"
android:textSize="17dp" />
<ImageView
android:id="#+id/divider_bottom"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/lblListHeader"
android:layout_centerHorizontal="true"
android:background="#drawable/divider" />
</RelativeLayout>