I have custom expandable cardview in which I want to show HighChart as expanded panel. For this I used the ViewStub to inflate the HighChart Layout. But on runtime it gives me "java.util.NoSuchElementException: HIOptions not found in HIChartView" exception.
private String title;
private View innerView;
private ViewGroup containerView;
private ImageButton arrowBtn;
private ImageButton headerIcon;
private TextView textViewTitle;
private TypedArray typedArray;
private int innerViewRes;
private Drawable iconDrawable;
private MaterialCardView card;
public static final int DEFAULT_ANIM_DURATION = 350;
private long animDuration = DEFAULT_ANIM_DURATION;
private final static int COLLAPSING = 0;
private final static int EXPANDING = 1;
private boolean isExpanded = false;
private boolean isExpanding = false;
private boolean isCollapsing = false;
private boolean expandOnClick = false;
private boolean startExpanded = false;
private int previousHeight = 0;
private OnExpandedListener listener;
public ExpandableCardViewHelper(Context context) {
super(context);
}
public ExpandableCardViewHelper(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initAttributes(context, attrs);
initView(context);
}
public ExpandableCardViewHelper(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttributes(context, attrs);
initView(context);
}
public ExpandableCardViewHelper(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private void initView(Context context){
//Inflating View
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.item_expandable_cardview, this);
}
private void initAttributes(Context context, AttributeSet attrs){
//Ottengo attributi
typedArray = context.obtainStyledAttributes(attrs, R.styleable.ExpandableCardView);
title = typedArray.getString(R.styleable.ExpandableCardView_title);
iconDrawable = typedArray.getDrawable(R.styleable.ExpandableCardView_icon);
innerViewRes = typedArray.getResourceId(R.styleable.ExpandableCardView_inner_view, View.NO_ID);
expandOnClick = typedArray.getBoolean(R.styleable.ExpandableCardView_expandOnClick, false);
animDuration = typedArray.getInteger(R.styleable.ExpandableCardView_animationDuration, DEFAULT_ANIM_DURATION);
startExpanded = typedArray.getBoolean(R.styleable.ExpandableCardView_startExpanded, false);
typedArray.recycle();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//Una volta che la view è inflatata setto tutto
arrowBtn = findViewById(R.id.arrow);
textViewTitle = findViewById(R.id.title);
headerIcon = findViewById(R.id.icon);
//Setting attributes
if(!TextUtils.isEmpty(title)) textViewTitle.setText(title);
if(iconDrawable != null){
headerIcon.setVisibility(VISIBLE);
headerIcon.setBackground(iconDrawable);
}
card = findViewById(R.id.card);
setInnerView(innerViewRes);
containerView = findViewById(R.id.viewContainer);
setElevation(DisplayMeasurementUtils.convertDpToPixels(getContext(), 4));
if(startExpanded){
setAnimDuration(0);
expand();
setAnimDuration(animDuration);
}
if(expandOnClick){
textViewTitle.setOnClickListener(defaultClickListener);
arrowBtn.setOnClickListener(defaultClickListener);
}
}
public void expand() {
final int initialHeight = card.getHeight();
if(!isMoving()) {
previousHeight = initialHeight;
}
card.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
int targetHeight = card.getMeasuredHeight();
if(targetHeight - initialHeight != 0) {
animateViews(initialHeight,
targetHeight - initialHeight,
EXPANDING);
}
}
public void collapse() {
int initialHeight = card.getMeasuredHeight();
if(initialHeight - previousHeight != 0) {
animateViews(initialHeight,
initialHeight - previousHeight,
COLLAPSING);
}
}
public boolean isExpanded() {
return isExpanded;
}
private void animateViews(final int initialHeight, final int distance, final int animationType){
Animation expandAnimation = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1){
//Setting isExpanding/isCollapsing to false
isExpanding = false;
isCollapsing = false;
if(listener != null){
if(animationType == EXPANDING){
listener.onExpandChanged(card,true);
}
else{
listener.onExpandChanged(card,false);
}
}
}
card.getLayoutParams().height = animationType == EXPANDING ? (int) (initialHeight + (distance * interpolatedTime)) :
(int) (initialHeight - (distance * interpolatedTime));
card.findViewById(R.id.viewContainer).requestLayout();
containerView.getLayoutParams().height = animationType == EXPANDING ? (int) (initialHeight + (distance * interpolatedTime)) :
(int) (initialHeight - (distance * interpolatedTime));
}
@Override
public boolean willChangeBounds() {
return true;
}
};
RotateAnimation arrowAnimation = animationType == EXPANDING ?
new RotateAnimation(0,180,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f) :
new RotateAnimation(180,0,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
arrowAnimation.setFillAfter(true);
arrowAnimation.setDuration(animDuration);
expandAnimation.setDuration(animDuration);
isExpanding = animationType == EXPANDING;
isCollapsing = animationType == COLLAPSING;
startAnimation(expandAnimation);
Log.d("SO","Started animation: "+ (animationType == EXPANDING ? "Expanding" : "Collapsing"));
arrowBtn.startAnimation(arrowAnimation);
isExpanded = animationType == EXPANDING;
}
private boolean isExpanding(){
return isExpanding;
}
private boolean isCollapsing(){
return isCollapsing;
}
private boolean isMoving(){
return isExpanding() || isCollapsing();
}
public void setOnExpandedListener(OnExpandedListener listener) {
this.listener = listener;
}
public void removeOnExpandedListener(){
this.listener = null;
}
public void setTitle(String title){
if(textViewTitle != null) textViewTitle.setText(title);
}
public void setTitle(int resId){
if(textViewTitle != null) textViewTitle.setText(resId);
}
public void setIcon(Drawable drawable){
if(headerIcon != null){
headerIcon.setBackground(drawable);
iconDrawable = drawable;
}
}
public void setIcon(int resId){
if(headerIcon != null){
iconDrawable = ContextCompat.getDrawable(getContext(), resId);
headerIcon.setBackground(iconDrawable);
}
}
private void setInnerView(int resId){
ViewStub stub = findViewById(R.id.viewStub);
stub.setLayoutResource(resId);
innerView = stub.inflate();
}
public View getInnerView(){
return innerView;
}
@Override
public void setOnClickListener(@Nullable OnClickListener l) {
if(arrowBtn != null) arrowBtn.setOnClickListener(l);
super.setOnClickListener(l);
}
public long getAnimDuration() {
return animDuration;
}
public void setAnimDuration(long animDuration) {
this.animDuration = animDuration;
}
private OnClickListener defaultClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
if(isExpanded()) collapse();
else expand();
}
};
/**
* Interfaces
*/
public interface OnExpandedListener {
void onExpandChanged(View v, boolean isExpanded);
}
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/default_card_height"
android:id="@+id/header">
<ImageButton
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="Prova"
android:padding="8dp"
android:maxLines="1"
android:layout_centerVertical="true"
android:textColor="@android:color/primary_text_light" />
<ImageButton
android:id="@+id/arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:padding="8dp"
android:background="?selectableItemBackgroundBorderless"
android:src="@drawable/ic_arrow_down"/>
</RelativeLayout>
<ViewStub
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/viewStub"
android:inflatedId="@+id/innerView"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.busisoft.ezeeoffice.helpers.ExpandableCardViewHelper
android:id="@+id/frag_order_placed_status_wise_order"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="Orders Status wise"
app:inner_view="@layout/chart_area"
app:expandOnClick="true" />
</LinearLayout>
<ImageButton
android:id="@+id/infoBtn"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:background="@null"
android:src="@drawable/ic_info_outline_white_24dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>