Skip to content

Instantly share code, notes, and snippets.

@wviana
Created April 8, 2016 18:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wviana/8a23ea62835b058fe62a67d80c37ad0a to your computer and use it in GitHub Desktop.
Save wviana/8a23ea62835b058fe62a67d80c37ad0a to your computer and use it in GitHub Desktop.
package neocom.dealerbook.views;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnCheckedChanged;
import butterknife.OnClick;
import neocom.dealerbook.R;
/**
* Created by wviana on 04/04/16.
*/
public class LayerView extends LinearLayout implements RadioGroup.OnCheckedChangeListener {
public static final int DURATION_MILLIS = 250;
@Bind(R.id.layer_options) LinearLayout layerOptions;
@Bind(R.id.layer_name) TextView layerName;
private boolean expanded = true;
private LayerPropertiesChangeListener layerPropertiesChangeListener;
@Bind(R.id.presenter_options) RadioGroup presenterSelector;
public static class Builder {
private String layerName;
private boolean expanded;
private LayerPropertiesChangeListener propertiesChangeListener;
private List<Integer> presenterIcons = new ArrayList<>();
private Context context;
public Builder(Context context){
this.context = context;
expanded = false;
}
public Builder layerName(String name){
this.layerName = name;
return this;
}
public Builder addPresenterIcon(int icon){
this.presenterIcons.add(icon);
return this;
}
public Builder propertiesChangeListerner(LayerPropertiesChangeListener listener){
this.propertiesChangeListener = listener;
return this;
}
public LayerView build(){
return new LayerView(this);
}
}
private LayerView(Builder builder){
this(builder.context);
layerName.setText(builder.layerName);
expanded = builder.expanded;
layerPropertiesChangeListener = builder.propertiesChangeListener;
for(int icon : builder.presenterIcons){
addPresenter(icon);
}
updatePresenterSelectorBackground();
if(presenterSelector.getChildCount() > 0 && presenterSelector.getCheckedRadioButtonId() == -1){
presenterSelector.check(0);
}
}
public LayerView(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.layer_view, this, true);
ButterKnife.bind(this);
presenterSelector.setOnCheckedChangeListener(this);
setOrientation(VERTICAL);
}
@OnClick(R.id.layer_name)
public void onLayerLabelClicked(){
if (!expanded) {
expand();
} else {
collapse();
}
}
public void expand(){
layerOptions.measure(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final int targetHeight = layerOptions.getMeasuredHeight();
layerOptions.setVisibility(VISIBLE);
layerOptions.requestLayout();
Animation a = new Animation(){
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
layerOptions.getLayoutParams().height = (interpolatedTime == 1)
? ViewGroup.LayoutParams.WRAP_CONTENT
: (int) (targetHeight * interpolatedTime);
layerOptions.requestLayout();
}
@Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration(DURATION_MILLIS);
layerOptions.startAnimation(a);
//layerOptions.animate().translationY(1f);
expanded = !expanded;
}
public void collapse(){
final int initialHeight = layerOptions.getMeasuredHeight();
Animation a = new Animation(){
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1f) {
layerOptions.setVisibility(GONE);
} else {
layerOptions.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);
layerOptions.requestLayout();
}
}
@Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration(DURATION_MILLIS);
layerOptions.startAnimation(a);
layerOptions.setVisibility(INVISIBLE);
//layerOptions.animate().translationY(-100f);
expanded = !expanded;
}
public void addPresenter(int icon){
RadioButton presenter = new RadioButton(getContext());
//Configura atributos padrão
Drawable drawable = getResources().getDrawable(icon);
presenter.setCompoundDrawables(drawable, null, null, null);
presenterSelector.addView(presenter);
presenter.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
presenter.getLayoutParams().height = presenter.getMeasuredHeight();
presenter.getLayoutParams().width = presenter.getMeasuredWidth();
presenter.requestLayout();
//updatePresenterSelectorBackground();
}
private void updatePresenterSelectorBackground(){
int childCount = presenterSelector.getChildCount();
for(int i = 0; i < childCount; i++){
View rb = getChildAt(i);
if(i == 0)
rb.setBackgroundResource(R.drawable.presenter_radiobutton_left);
else if (i == childCount - 1)
rb.setBackgroundResource(R.drawable.presenter_radiobutton_right);
else
rb.setBackgroundResource(R.drawable.presenter_radiobutton_center);
}
presenterSelector.requestLayout();
}
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
if(layerPropertiesChangeListener != null){
layerPropertiesChangeListener.onPresenterChange(i);
}
}
@OnCheckedChanged(R.id.layer_switch)
public void onChangeLayerEnabled(boolean isLayerOn){
if(layerPropertiesChangeListener != null){
layerPropertiesChangeListener.onLayerEnableChange(isLayerOn);
}
}
//Presenter Change
public interface LayerPropertiesChangeListener {
void onPresenterChange(int presenterPosition);
void onLayerEnableChange(boolean enabled);
}
public LayerPropertiesChangeListener getLayerPropertiesChangeListener() {
return layerPropertiesChangeListener;
}
public void setLayerPropertiesChangeListener(LayerPropertiesChangeListener layerPropertiesChangeListener) {
this.layerPropertiesChangeListener = layerPropertiesChangeListener;
}
}
04-08 14:53:28.672 22193-22193/neocom.dealerbook E/AndroidRuntime: FATAL EXCEPTION: main
Process: neocom.dealerbook, PID: 22193
java.lang.RuntimeException: Unable to start activity ComponentInfo{neocom.dealerbook/neocom.dealerbook.activities.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setBackgroundResource(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setBackgroundResource(int)' on a null object reference
at neocom.dealerbook.views.LayerView.updatePresenterSelectorBackground(LayerView.java:185)
at neocom.dealerbook.views.LayerView.<init>(LayerView.java:80)
at neocom.dealerbook.views.LayerView.<init>(LayerView.java:28)
at neocom.dealerbook.views.LayerView$Builder.build(LayerView.java:65)
at neocom.dealerbook.models.layer.Layer.getView(Layer.java:216)
at neocom.dealerbook.activities.MainActivity.onCreate(MainActivity.java:109)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387) 
at android.app.ActivityThread.access$800(ActivityThread.java:151) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5254) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment