I have a screen with a Recyclerview and others Elements inside of LinearLayout. The problem is when I remove a item of the RecyclerView, animateLayoutChanges doesn't work in this case. Does anayone know why this happen??
XML
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.alvaro.resizetest.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="#+id/test1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/colorAccent"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LinearLayout"
android:textColor="#FFFFFF"
android:textSize="22sp"/>
</LinearLayout>
<LinearLayout
android:id="#+id/test2"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/colorPrimaryDark"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LinearLayout"
android:textColor="#FFFFFF"
android:textSize="22sp"/>
</LinearLayout>
<LinearLayout
android:id="#+id/test3"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/colorAccent"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LinearLayout"
android:textColor="#FFFFFF"
android:textSize="22sp"/>
</LinearLayout>
<LinearLayout
android:id="#+id/test4"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/colorPrimaryDark"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LinearLayout"
android:textColor="#FFFFFF"
android:textSize="22sp"/>
</LinearLayout>
</LinearLayout>
JAVA
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
Adapter adapter = new Adapter();
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
recyclerView.setNestedScrollingEnabled(true);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View view) {
view.setVisibility(View.GONE);
}
};
findViewById(R.id.test1).setOnClickListener(listener);
findViewById(R.id.test2).setOnClickListener(listener);
findViewById(R.id.test3).setOnClickListener(listener);
findViewById(R.id.test4).setOnClickListener(listener);
}
class Adapter extends RecyclerView.Adapter<Adapter.Holder>{
int size = 3;
public Adapter() {
}
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = getLayoutInflater().inflate(R.layout.item, parent, false);
return new Holder(view);
}
#Override
public void onBindViewHolder(Holder holder, int position) {
}
#Override
public int getItemCount() {
return size;
}
class Holder extends RecyclerView.ViewHolder {
public Holder(final View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
size --;
notifyItemRemoved(getAdapterPosition());
}
});
}
}
}
After a while I got a solution. I made a function to animate the recyclerView height.
JAVA
public class MainActivity extends AppCompatActivity {
private final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
Adapter adapter = new Adapter(recyclerView);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this) {
#Override
public boolean canScrollVertically() {
return false;
}
};
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);
recyclerView.setNestedScrollingEnabled(true);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View view) {
view.setVisibility(View.GONE);
}
};
findViewById(R.id.test1).setOnClickListener(listener);
findViewById(R.id.test2).setOnClickListener(listener);
findViewById(R.id.test3).setOnClickListener(listener);
findViewById(R.id.test4).setOnClickListener(listener);
}
public void animateHeight(final View v, final int height) {
final int initialHeight = v.getMeasuredHeight();
int duration = 500;
Interpolator interpolator = new AccelerateInterpolator(2);
// I have to set the same height before the animation because there is a glitch
// in the beginning of the animation
v.getLayoutParams().height = initialHeight;
v.requestLayout();
Animation a = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
Log.d(TAG, "InterpolatedTime: " + interpolatedTime);
Log.d(TAG, "Collapsing height: " + (initialHeight - (int) (height * interpolatedTime)));
v.getLayoutParams().height = initialHeight - (int) (height * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration(duration);
a.setInterpolator(interpolator);
v.startAnimation(a);
}
class Adapter extends RecyclerView.Adapter<Adapter.Holder> {
RecyclerView mRecyclerView;
int size = 3;
public Adapter(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
}
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = getLayoutInflater().inflate(R.layout.item, parent, false);
return new Holder(view);
}
#Override
public void onBindViewHolder(Holder holder, int position) {
}
#Override
public int getItemCount() {
return size;
}
class Holder extends RecyclerView.ViewHolder {
public Holder(final View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
size--;
notifyItemRemoved(getAdapterPosition());
animateHeight((View) itemView.getParent(), itemView.getMeasuredHeight());
}
});
}
}
}
}
What worked for me was simply adding the following code to onCreate:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
((ViewGroup) findViewById(R.id.llRoot)).getLayoutTransition()
.enableTransitionType(LayoutTransition.CHANGING);
}
where llRoot is your LinearLayout containing RecyclerView.
You do need to keep android:animateLayoutChanges="true" on your LinearLayout, otherwise it crashes.
I believe if you want to support this below JellyBean, you would need your custom solution.
Explanation on the solution is here: https://proandroiddev.com/the-little-secret-of-android-animatelayoutchanges-e4caab2fddec
Related
I have implemented a RecyclerView inside a ConstraintLayout. I am having one child image element inside the layout. But when I click the child image, it always returns the ConstraintLayout, not the clicked image.
Could you please tell me why this is happening, what is the solution for this ?
I separately did bind listener to image, it is working but not able to get the RecyclerItem object. I need RecyclerItem object for the position to proceed.
I implemented it by binding elements via onBindViewholder method in Adapter. Below are the codes
customAdapter = new GridViewAdapter(recyclerItems, 1, this.getContext().getPackageName(),
new GridViewAdapter.OnItemClickListener(){
#Override
public void onItemClick(RecyclerItem item) {
CommonUtil.addFragment("REP", Constants.CONTAINER_HOME,
new ModifyFragment(), getActivity(), null);
}
}, R.layout.rec_view_item_stock, Constants.V_SPAN_LIST_8);
RecyclerView recyclerView = view.findViewById(R.id.stockListRecView);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setLayoutManager(new GridLayoutManager(this.getContext(), 1));
recyclerView.setAdapter(customAdapter);
//Adapter
public class GridViewAdapter extends RecyclerView.Adapter<GridViewAdapter.ViewHolder>{
private List<RecyclerItem> dataItems;
private int hSpan = 1;
private String packageName;
private final OnItemClickListener listener;
private int inflator;
private int vSpan;
public interface OnItemClickListener {
void onItemClick(RecyclerItem item);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final ConstraintLayout constraintLayout;
private final TextView textView;
private final ImageView imageView;
private Object obj;
public ViewHolder(View view) {
super(view);
constraintLayout = (ConstraintLayout) view.findViewById(R.id.rec_content_layout);
textView = constraintLayout.findViewById(R.id.recTextView);
imageView = constraintLayout.findViewById(R.id.recImage);
}
public void bind(final RecyclerItem item, final OnItemClickListener listener) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(item);
}
});
}
public TextView getTextView() {
return textView;
}
public ImageView getImageView() {
return imageView;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
public GridViewAdapter(List<RecyclerItem> items, int spanCount, String packageName, OnItemClickListener listener,
int inflator, int vSpan) {
dataItems = items;
this.hSpan = spanCount;
this.packageName = packageName;
this.listener = listener;
this.inflator = inflator;
this.vSpan = vSpan;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int gridType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(inflator, viewGroup, false);
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = (viewGroup.getResources().getDisplayMetrics().widthPixels / hSpan) - 24;
if(Constants.V_SPAN_GRID == vSpan) {
layoutParams.height = layoutParams.width;
} else {
layoutParams.height = (viewGroup.getResources().getDisplayMetrics().widthPixels / vSpan);
}
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
viewHolder.getTextView().setText(dataItems.get(position).getText());
int imgId = viewHolder.getImageView().getResources().getIdentifier(
dataItems.get(position).getImageName(), "drawable", packageName);
viewHolder.getImageView().setImageResource(imgId);
viewHolder.setObj(dataItems.get(position));
viewHolder.bind(dataItems.get(position), listener);
}
#Override
public int getItemCount() {
return dataItems.size();
}
//item layout
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/rec_content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_marginTop="8dp"
android:layout_marginLeft="4dp"
android:padding="8dp"
android:background="#drawable/border_top_bottom" >
<androidx.constraintlayout.widget.Guideline
android:id="#+id/viewstock_gline_1_v"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.6"/>
<ImageView
android:id="#+id/recImage"
android:background="#color/colorPrimaryDark"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<TextView
android:id="#+id/recTextView"
app:layout_constraintLeft_toRightOf="#+id/recImage"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<ImageView
android:id="#+id/editstock_image"
android:src="#drawable/ic_edit_stock"
android:background="#color/colorPrimaryDark"
app:layout_constraintRight_toLeftOf="#+id/deletestock_image"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<ImageView
android:id="#+id/deletestock_image"
android:src="#drawable/ic_delete_stock"
android:background="#color/colorPrimaryDark"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout>```
Try this!
public void bind(final RecyclerItem item, final OnItemClickListener listener, TextView itemTextView) {
itemTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(item);
}
});
}
Pass every item text view instance from the view holder or fro onBindViewHolder itself implement onclick listener
I have two RecyclerViews on my screen. And I need to scroll both at the same time on the same distance programmatically. But if I do it fast - the RecyclerViews desynchronizes.
In this source code you should fast click on button in the right top and will see the result.
This is Activity, where button listener for scrolling lists created:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView1;
private RecyclerView recyclerView2;
private Adapter adapter1;
private Adapter adapter2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView1 = findViewById(R.id.recycler_view1);
recyclerView2 = findViewById(R.id.recycler_view2);
adapter1 = new Adapter();
recyclerView1.setLayoutManager(new LinearLayoutManager(this));
recyclerView1.setAdapter(adapter1);
adapter2 = new Adapter();
recyclerView2.setLayoutManager(new LinearLayoutManager(this));
recyclerView2.setAdapter(adapter2);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
recyclerView1.smoothScrollBy(0, 400);
recyclerView2.smoothScrollBy(0, 400);
}
});
}
}
Adapter for lists:
public class Adapter extends RecyclerView.Adapter<Adapter.Holder>{
private boolean changeHeight = false;
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new Holder(view);
}
#Override
public void onBindViewHolder(Holder holder, int position) {
holder.setContent(String.valueOf(position), position % 2 == 0 ? R.color.colorPrimary : R.color.colorAccent);
if (changeHeight && position == 3) holder.changeHeight();
}
#Override
public int getItemCount() {
return 100;
}
class Holder extends RecyclerView.ViewHolder {
private View view;
private TextView textView;
public Holder(View itemView) {
super(itemView);
view = itemView;
textView = itemView.findViewById(R.id.text_view);
}
public void setContent(String text, int colorRes) {
textView.setText(text);
textView.setBackgroundResource(colorRes);
}
public void changeHeight() {
ViewGroup.LayoutParams params = view.getLayoutParams();
params.height = view.getHeight() * 2;
view.setLayoutParams(params);
}
}
}
This is activity_main.xml layout for Activity
<?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="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view1"
android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="match_parent"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view2"
android:layout_width="0dp"
android:layout_weight="0.5"
android:layout_height="match_parent"/>
<Button
android:id="#+id/button"
android:layout_width="100dp"
android:layout_height="100dp"/>
</LinearLayout>
Item for RecyclerView item.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="100dp">
<TextView
android:id="#+id/text_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"/>
</RelativeLayout>
Crude solution is copying scroll of first recycler into the second one:
recyclerView1.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
recyclerView2.scrollBy(dx, dy);
}
});
Then proceed to smoothScroll only recyclerView1.
i already success to make one Recyclerview and i want to add new Recyclerview Horizontal on top. i will explain in my code :
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayListUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
id:arrayList is my first Recyclerview have name xml feeds_listview
id:arrayListUser is my new Recyclerview, i want make this Recyclerview Horizontal
xml for new Recylerview is feeds_listviewUser
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profil"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="30dp"
android:layout_gravity="center"
android:src="#drawable/cthprofil" />
<TextView
android:id="#+id/fullName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="5dp"
android:layout_marginBottom="20"
android:text="Megi Fernanda"
android:textSize="17sp"
android:textColor="#color/colordefault"
android:textStyle="bold" />
</LinearLayout>
and this is my class adapter
public class FeedsCustomAdapter extends RecyclerView.Adapter<FeedsCustomAdapter.ViewHolder> {
private Context context;
private List<FeedsAdapter> feeds_list;
private ArrayList<Feeds> mFeedsList = new ArrayList<Feeds>();
private OnItemClickListener mListener;
private OnItemClickListener mListener2;
public FeedsCustomAdapter(Context context, ArrayList<Feeds> mFeedsList) {
this.context = context;
this.mFeedsList = mFeedsList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.feeds_listview, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Feeds feed = getFeeds().get(position);
int textColor = context.getResources().getColor(R.color.btn_next);
int textColor2 = context.getResources().getColor(R.color.text_color_black);
holder.fullName.setText(feed.user.fullName);
holder.location.setText(feed.user.location);
holder.topic.setText(Html.fromHtml( "Menyelesaikan Tantangan " + " <font color = '" + String.valueOf(textColor2) + "'>" + feed.topic + "</font>" ) );
Picasso.with(context)
.load(feed.user.avatar)
.into(holder.profile);
PrettyTime prettyTime = new PrettyTime();
String times = prettyTime.format(DateUtil.timeMilisTodate(feed.timestamp * 1000));
holder.times.setText(times);
}
#Override
public int getItemCount() {
return mFeedsList.size();
}
public ArrayList<Feeds> getFeeds() {
return mFeedsList;
}
public void setComplete(int position) {
mFeedsList.get(position).isComplete = 1;
}
public boolean last() {
boolean result = false;
int total = mFeedsList.size();
for (int i = 0; i < mFeedsList.size(); i++) {
if (mFeedsList.get(i).isComplete == 1) {
total--;
}
}
if (total == 1) {
result = true;
}
return result;
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView fullName;
public TextView location;
public TextView topic;
public ImageView profile;
public TextView times;
public ViewHolder(View itemView) {
super(itemView);
fullName = (TextView) itemView.findViewById(R.id.fullName);
location = (TextView) itemView.findViewById(R.id.location);
topic = (TextView) itemView.findViewById(R.id.topic);
profile = (ImageView) itemView.findViewById(R.id.profil);
times = (TextView) itemView.findViewById(R.id.times);
profile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener2 != null){
mListener2.onItemClick2(v ,getPosition());
}
}
});
topic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener != null){
mListener.onItemClick(v ,getPosition());
}
}
});
}
}
public void setClickListener(OnItemClickListener clickListener) {
this.mListener = clickListener;
}
public void setClickListenerProfile(OnItemClickListener clickListener2){
this.mListener2 = clickListener2;
}
public interface OnItemClickListener {
public abstract void onItemClick(View view, int position);
public abstract void onItemClick2(View view, int position);
}
so, in my code i success to display first recylerview with my first xml and i want add new recylerview horizontal with new xml feeds_listviewUser
You can use LinearLayout to wrap both recyclerView.
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayListUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
And assign horizontal layout manager to one recyclerview and vertical layout manager to other
LinearLayoutManager userManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
arrayListUser.setLayoutManager(userManager);
LinearLayoutManager listManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
arrayList.setLayoutManager(listManager);
Put your recyclerviews in Relative layout.
First add horizontal recyclerView to alignParentTop true and fix height according to visibility of feeds_listviewUser next add vertical recyclerView with layout_below horizontal recyclerview id.
This is my Adapter class
public class NewFeePlanAdapter extends RecyclerView.Adapter<NewFeePlanAdapter.MyViewHolder> {
Context context;
ArrayList<FeeTypeModel> feeTypeModelArrayList;
public NewFeePlanAdapter(Context context, ArrayList<FeeTypeModel> feeTypeModelArrayList){
this.context = context;
this.feeTypeModelArrayList = feeTypeModelArrayList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.new_fee_list_row, parent,false);
MyViewHolder myViewHolder = new MyViewHolder(itemView,new MyCustomEditTextListener());
return myViewHolder;
}
FeeTypeModel feeTypeModel;
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
feeTypeModel = feeTypeModelArrayList.get(position);
holder.fee_type_name_tv.setText(feeTypeModel.getFeeType().toString());
if (feeTypeModel.getLinearLayout()!=null) {
holder.new_plan_main_ll.addView(feeTypeModel.getLinearLayout());
}
holder.myCustomEditTextListener.updatePosition(position);
holder.fee_amount_et.setText( feeTypeModelArrayList.get(position).getAmount());
holder.fee_type_cb.setOnCheckedChangeListener(null);
holder.fee_type_cb.setChecked(feeTypeModel.isSelectPlan());
holder.fee_type_cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
feeTypeModelArrayList.get(position).setSelectPlan(isChecked);
}
});
holder.add_installments_iv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (holder.fee_amount_et.getText().length() == 0){
Toast.makeText(context,"Please Enter Amount",Toast.LENGTH_LONG).show();
}else {
showDialogForNumberOfInstallments(v,position,Long.parseLong(holder.fee_amount_et.getText().toString()));
}
}
});
}
#Override
public int getItemCount() {
return feeTypeModelArrayList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView fee_type_name_tv;
EditText fee_amount_et;
ImageView add_installments_iv;
CheckBox fee_type_cb;
public MyCustomEditTextListener myCustomEditTextListener;
LinearLayout new_plan_main_ll;
public MyViewHolder(View view, MyCustomEditTextListener myCustomEditTextListener) {
super(view);
new_plan_main_ll = (LinearLayout)view.findViewById(R.id.new_plan_main_ll);
fee_type_cb = (CheckBox) view.findViewById(R.id.fee_type_cb);
fee_type_name_tv = (TextView) view.findViewById(R.id.fee_type_name_tv);
fee_amount_et = (EditText) view.findViewById(R.id.fee_amount_et);
add_installments_iv = (ImageView)view.findViewById(R.id.add_installments_iv);
this.myCustomEditTextListener = myCustomEditTextListener;
this.fee_amount_et.addTextChangedListener(myCustomEditTextListener);
}
}
private class MyCustomEditTextListener implements TextWatcher {
private int position;
public void updatePosition(int position) {
this.position = position;
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
// no op
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
feeTypeModelArrayList.get(position).setAmount( charSequence.toString());
}
#Override
public void afterTextChanged(Editable editable) {
// no op
}
}
AutoCompleteTextView new_fee_plan_name_act;
EditText numberOfInstallments_et;
int selectedPosition;
private void showDialogForNumberOfInstallments(View v,int position, final long amount){
selectedPosition = position;
// Create custom dialog object
final Dialog dialog = new Dialog(context);
// Include dialog.xml file
dialog.setContentView(R.layout.new_plan_name_dialog);
dialog.setTitle("Installments");
new_fee_plan_name_act = (AutoCompleteTextView) dialog.findViewById(R.id.new_fee_plan_name_act);
new_fee_plan_name_act.setVisibility(View.GONE);
numberOfInstallments_et = (EditText)dialog.findViewById(R.id.numberOfInstallments_et);
numberOfInstallments_et.setVisibility(View.VISIBLE);
new_fee_plan_name_act.setHint("Enter Number Of Installments");
dialog.setCancelable(false);
dialog.show();
Button feePlan_cancel_bt = (Button) dialog.findViewById(R.id.feePlan_cancel_bt);
// if decline button is clicked, close the custom dialog
feePlan_cancel_bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Close dialog
dialog.dismiss();
}
});
Button FeePlan_create_bt = (Button) dialog.findViewById(R.id.FeePlan_create_bt);
FeePlan_create_bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (numberOfInstallments_et.getText().toString().length()==0){
Toast.makeText(context,"Please Enter New number 0f Installments",Toast.LENGTH_LONG).show();
}else {
FeeTypeModel feeTypeModel11 = feeTypeModelArrayList.get(selectedPosition);
if (feeTypeModel11.getLinearLayout()!=null) {
feeTypeModel11.getLinearLayout().removeView(v);
}
LinearLayout layout = new LinearLayout(context);
layout.setLayoutParams(new LinearLayout.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));
layout.setOrientation(LinearLayout.VERTICAL);
// Toast.makeText(context,"Entered Installments "+numberOfInstallments_et.getText().toString(),Toast.LENGTH_LONG).show();
int WrapWidth = LinearLayout.LayoutParams.WRAP_CONTENT;
int WrapHeight = LinearLayout.LayoutParams.WRAP_CONTENT;
int length = Integer.parseInt(numberOfInstallments_et.getText().toString());
long instAmount = amount/length;
for (int i=0;i<length;i++){
TextView t = new TextView(context);
t.setText("Installment"+i+" "+instAmount);
layout.addView(t,WrapWidth,WrapHeight);
}
feeTypeModel11.setLinearLayout(layout);
dialog.dismiss();
notifyDataSetChanged();
}
}
});
}
}
this is my new_fee_list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:elevation="6dp"
android:layout_marginTop="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:layout_marginBottom="#dimen/activity_horizontal_margin"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/new_plan_main_ll"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<CheckBox
android:id="#+id/fee_type_cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/fee_type_name_tv"
android:text="fsdfdsf"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_marginTop="#dimen/activity_horizontal_margin"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_toLeftOf="#+id/add_installments_iv"
android:layout_height="wrap_content">
<EditText
android:id="#+id/fee_amount_et"
android:layout_width="130dp"
android:layout_height="wrap_content"
android:imeActionId="#+id/login"
android:imeActionLabel="#string/action_sign_in_short"
android:imeOptions="actionUnspecified"
android:maxLines="1"
android:hint="Enter Amount"
android:inputType="number"
android:singleLine="true"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</android.support.design.widget.TextInputLayout>
<ImageView
android:id="#+id/add_installments_iv"
android:layout_width="wrap_content"
android:layout_marginLeft="#dimen/activity_horizontal_margin"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:src="#android:drawable/ic_input_add"
android:layout_height="wrap_content" />
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
//This is my main Activity class
public class NewFeePlanActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_fee_plan);
RecyclerView fee_plans_rv = (RecyclerView)findViewById(R.id.fee_plans_rv);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
fee_plans_rv.setLayoutManager(mLayoutManager);
NewFeePlanAdapter newFeePlanAdapter = new NewFeePlanAdapter(NewFeePlanActivity.this, feeTypeModelArrayList);
fee_plans_rv.setAdapter(newFeePlanAdapter);
}}
I am using above code,but my problem is adding specific position on list
** As showed above image how i need to dynamically add and remove the views each item positionin recycler view,can any one guide me with code,
your response will be appreciated..... **
I am trying to use the SwipeDismissBehavoir from design support library. I've list items in RecyclerView and swiping an item have to dismiss (like google inbox app) .
I've set the listener for the RecyclerView items but the SwipeDismissBehavior onDismiss listener is not getting called.
SwipeDismissBehavior behavior = new SwipeDismissBehavior();
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams)mItemLayout.getLayoutParams();
params.setBehavior(behavior);
behavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
#Override
public void onDismiss(View view) {
}
#Override
public void onDragStateChanged(int i) {
}
});
mItemLayout.setLayoutParams(params);
Here is example how delete row by swipe
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
// init layout manager
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
final ArrayList<String> list = new ArrayList<String>();
list.add("Item1");
list.add("Item2");
list.add("Item3");
list.add("Item4");
list.add("Item5");
list.add("Item6");
final MyAdapter adapter = new MyAdapter(list);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
ItemTouchHelper swipeToDismissTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
// callback for drag-n-drop, false to skip this feature
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// callback for swipe to dismiss, removing item from data and adapter
list.remove(viewHolder.getAdapterPosition());
adapter.notifyItemRemoved(viewHolder.getAdapterPosition());
}
});
swipeToDismissTouchHelper.attachToRecyclerView(recyclerView);
}
Adapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
ArrayList<String> dataset_;
public static class MyViewHolder extends RecyclerView.ViewHolder{
public Button mBtn;
public TextView mTextView2;
public MyViewHolder(View v){
super(v);
mBtn = (Button) itemView.findViewById(R.id.delete);
mTextView2 = (TextView) itemView.findViewById(R.id.textView2);
}
}
public MyAdapter (ArrayList<String> dataset){
dataset_ = dataset;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view,parent,false);
MyViewHolder myViewHolder = new MyViewHolder(v);
return myViewHolder;
}
#Override
public void onBindViewHolder(MyViewHolder holder,int position){
holder.mTextView2.setText(dataset_.get(position));
}
#Override
public int getItemCount(){
return dataset_.size();
}
}
Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="vertical"
android:padding="16dp">
<TextView
style="?android:listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/heading_dismissable_recycler_view" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Item in RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/textView2"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/delete"
android:text="Delete"
android:layout_marginLeft="150dp"
android:visibility="invisible" />
</LinearLayout>
</LinearLayout>
Tried with single view.
I can know the view was dismissed, but I'm wondering how to restore the view like Gmail.
Layout:
<android.support.design.widget.CoordinatorLayout
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"
android:id="#+id/coordinatorLayout"
tools:context=".MainActivity">
<android.support.v7.widget.CardView
android:id="#+id/cardView"
android:layout_margin="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="Haha"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v7.widget.CardView>
</android.support.design.widget.CoordinatorLayout>
Activity:
public class MainActivity extends AppCompatActivity {
private CoordinatorLayout coordinatorLayout;
private CardView cardView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);
cardView = (CardView) findViewById(R.id.cardView);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) cardView.getLayoutParams();
final SwipeDismissBehavior<CardView> behavior = new SwipeDismissBehavior();
behavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_START_TO_END);
behavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
#Override
public void onDismiss(final View view) {
Snackbar.make(coordinatorLayout, "Done", Snackbar.LENGTH_LONG)
.show();
}
#Override
public void onDragStateChanged(int i) {
}
});
params.setBehavior(behavior);
cardView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return behavior.onTouchEvent(coordinatorLayout, cardView, event);
}
});
}
}
I have succeeded implementing the support library SwipeDismissBehavior and it actually requires CoordinatorLayout inside of each inflated card view layout. I haven't noticed any performance issues so far, so I assume CoordinatorLayout is not so heavy for the UI. There is probably a better way, but I still haven't found it.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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="wrap_content"
android:background="#FF0000">
<LinearLayout
android:id="#+id/card_content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#FFFFFF"
android:padding="20dp">
<TextView
android:id="#+id/card_context_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test text"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
In the constructor of the RecyclerView.ViewHolder implementation class (which is inside the Adapter) I have added:
View cardContentLayout = view.findViewById(R.id.card_content_layout);
SwipeDismissBehavior<View> swipeDismissBehavior = new SwipeDismissBehavior<>();
swipeDismissBehavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_END_TO_START);
swipeDismissBehavior.setListener(new SwipeDismissBehavior.OnDismissListener() {
#Override
public void onDismiss(View view) {
int adapterPosition = getAdapterPosition();
deleteListener.onDismissGesture(view, adapterPosition);
}
#Override
public void onDragStateChanged(int state) { }
});
CoordinatorLayout.LayoutParams coordinatorParams = (CoordinatorLayout.LayoutParams) cardContentLayout.getLayoutParams();
coordinatorParams.setBehavior(swipeDismissBehavior);
cardContentLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return swipeDismissBehavior.onTouchEvent((CoordinatorLayout) itemView, cardContentLayout, event);
}
});