1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.supportv7.widget.touch; 18 19 import android.app.Activity; 20 import android.graphics.Canvas; 21 import android.os.Bundle; 22 import android.view.LayoutInflater; 23 import android.view.View; 24 import android.view.ViewGroup; 25 import android.widget.Button; 26 import android.widget.TextView; 27 28 import androidx.annotation.NonNull; 29 import androidx.annotation.Nullable; 30 import androidx.cardview.widget.CardView; 31 import androidx.recyclerview.widget.ItemTouchHelper; 32 import androidx.recyclerview.widget.LinearLayoutManager; 33 import androidx.recyclerview.widget.RecyclerView; 34 35 import com.example.android.supportv7.Cheeses; 36 import com.example.android.supportv7.R; 37 import com.example.android.supportv7.widget.util.ConfigToggle; 38 import com.example.android.supportv7.widget.util.ConfigViewHolder; 39 40 import java.util.ArrayList; 41 import java.util.Arrays; 42 import java.util.List; 43 44 /** 45 * Sample activity from which ItemTouchHelper demo activities inherit. 46 */ 47 abstract public class ItemTouchHelperActivity extends Activity { 48 49 public RecyclerView mRecyclerView; 50 51 public ItemTouchAdapter mAdapter; 52 53 public ItemTouchHelper mItemTouchHelper; 54 55 public ItemTouchHelper.Callback mCallback; 56 57 private ConfigToggle[] mConfigToggles; 58 59 @Override onCreate(Bundle savedInstanceState)60 public void onCreate(Bundle savedInstanceState) { 61 super.onCreate(savedInstanceState); 62 setContentView(R.layout.activity_item_touch); 63 mRecyclerView = findViewById(R.id.recycler_view); 64 mRecyclerView.setHasFixedSize(true); 65 mAdapter = createAdapter(); 66 mRecyclerView.setAdapter(mAdapter); 67 mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 68 mItemTouchHelper = createItemTouchHelper(); 69 mItemTouchHelper.attachToRecyclerView(mRecyclerView); 70 initToggles(); 71 } 72 initToggles()73 private void initToggles() { 74 mConfigToggles = createConfigToggles(); 75 RecyclerView configView = findViewById(R.id.config_recycler_view); 76 configView.setAdapter(new RecyclerView.Adapter<ConfigViewHolder>() { 77 @Override 78 public ConfigViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 79 return new ConfigViewHolder(LayoutInflater.from(parent.getContext()) 80 .inflate(R.layout.config_view_toggle, parent, false)); 81 } 82 83 @Override 84 public void onBindViewHolder(ConfigViewHolder holder, int position) { 85 ConfigToggle toggle = mConfigToggles[position]; 86 holder.bind(toggle); 87 } 88 89 @Override 90 public int getItemCount() { 91 return mConfigToggles.length; 92 } 93 }); 94 configView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, 95 false)); 96 configView.setHasFixedSize(true); 97 } 98 createConfigToggles()99 abstract ConfigToggle[] createConfigToggles(); 100 createItemTouchHelper()101 public ItemTouchHelper createItemTouchHelper() { 102 mCallback = createCallback(); 103 return new ItemTouchHelper(mCallback); 104 } 105 createCallback()106 public ItemTouchHelper.Callback createCallback() { 107 return new ItemTouchHelper.Callback() { 108 @Override 109 public int getMovementFlags(@NonNull RecyclerView recyclerView, 110 @NonNull RecyclerView.ViewHolder viewHolder) { 111 return ItemTouchHelperActivity.this.getMovementFlags(recyclerView, viewHolder); 112 } 113 114 @Override 115 public boolean onMove(@NonNull RecyclerView recyclerView, 116 @NonNull RecyclerView.ViewHolder viewHolder, 117 @NonNull RecyclerView.ViewHolder target) { 118 mAdapter.move(viewHolder.getAdapterPosition(), target.getAdapterPosition()); 119 return true; 120 } 121 122 @Override 123 public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { 124 mAdapter.delete(viewHolder.getAdapterPosition()); 125 } 126 127 @Override 128 public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, 129 int actionState) { 130 super.onSelectedChanged(viewHolder, actionState); 131 ItemTouchHelperActivity.this.onSelectedChanged(viewHolder, actionState); 132 } 133 134 @Override 135 public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, 136 @NonNull RecyclerView.ViewHolder viewHolder, 137 float dX, float dY, int actionState, boolean isCurrentlyActive) { 138 if (ItemTouchHelperActivity.this.onChildDraw(c, recyclerView, viewHolder, 139 dX, dY, actionState, isCurrentlyActive)) { 140 return; 141 } 142 super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, 143 isCurrentlyActive); 144 } 145 146 @Override 147 public void onChildDrawOver(@NonNull Canvas c, @NonNull RecyclerView recyclerView, 148 RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, 149 boolean isCurrentlyActive) { 150 if (ItemTouchHelperActivity.this.onChildDrawOver(c, recyclerView, viewHolder, 151 dX, dY, actionState, isCurrentlyActive)) { 152 return; 153 } 154 super.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, 155 isCurrentlyActive); 156 } 157 158 @Override 159 public boolean isLongPressDragEnabled() { 160 return ItemTouchHelperActivity.this.isLongPressDragEnabled(); 161 } 162 163 @Override 164 public boolean isItemViewSwipeEnabled() { 165 return ItemTouchHelperActivity.this.isPointerSwipeEnabled(); 166 } 167 168 @Override 169 public void clearView(@NonNull RecyclerView recyclerView, 170 @NonNull RecyclerView.ViewHolder viewHolder) { 171 super.clearView(recyclerView, viewHolder); 172 ItemTouchHelperActivity.this.clearView(viewHolder); 173 } 174 }; 175 } 176 177 /** 178 * @return True if we should NOT call parent 179 */ 180 public boolean onChildDraw(Canvas c, RecyclerView recyclerView, 181 RecyclerView.ViewHolder viewHolder, 182 float dX, float dY, int actionState, boolean isCurrentlyActive) { 183 return false; 184 } 185 186 /** 187 * @return True if we should NOT call parent 188 */ 189 public boolean onChildDrawOver(Canvas c, RecyclerView recyclerView, 190 RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, 191 boolean isCurrentlyActive) { 192 return false; 193 } 194 195 public void clearView(RecyclerView.ViewHolder viewHolder) { 196 197 } 198 199 public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { 200 201 } 202 203 public boolean isLongPressDragEnabled() { 204 return true; 205 } 206 207 public boolean isPointerSwipeEnabled() { 208 return true; 209 } 210 211 public ItemTouchViewHolder onCreateViewHolder(ViewGroup parent) { 212 return new ItemTouchViewHolder( 213 LayoutInflater.from(parent.getContext()) 214 .inflate(R.layout.touch_item, parent, false)); 215 } 216 217 abstract public int getMovementFlags(RecyclerView recyclerView, 218 RecyclerView.ViewHolder viewHolder); 219 220 public ItemTouchAdapter createAdapter() { 221 return new ItemTouchAdapter(); 222 } 223 224 public void onBind(ItemTouchViewHolder viewHolder) { 225 226 } 227 228 public void onCreateViewHolder(ItemTouchViewHolder viewHolder) { 229 230 } 231 232 public class ItemTouchViewHolder extends RecyclerView.ViewHolder { 233 234 public final TextView textView; 235 236 public final Button actionButton; 237 238 public final CardView cardView; 239 240 public final View overlay; 241 242 public ItemTouchViewHolder(View itemView) { 243 super(itemView); 244 cardView = (CardView) itemView; 245 textView = (TextView) itemView.findViewById(R.id.text_view); 246 actionButton = (Button) itemView.findViewById(R.id.action_button); 247 overlay = itemView.findViewById(R.id.overlay); 248 } 249 } 250 251 public class ItemTouchAdapter extends RecyclerView.Adapter<ItemTouchViewHolder> { 252 253 private List<String> mItems = new ArrayList<String>(); 254 255 public ItemTouchAdapter() { 256 mItems.addAll(Arrays.asList(Cheeses.sCheeseStrings)); 257 } 258 259 @Override 260 public ItemTouchViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 261 return ItemTouchHelperActivity.this.onCreateViewHolder(parent); 262 } 263 264 @Override 265 public void onBindViewHolder(ItemTouchViewHolder holder, int position) { 266 holder.textView.setText(mItems.get(position)); 267 onBind(holder); 268 } 269 270 public void delete(int position) { 271 mItems.remove(position); 272 notifyItemRemoved(position); 273 } 274 275 public void move(int from, int to) { 276 String prev = mItems.remove(from); 277 mItems.add(to > from ? to - 1 : to, prev); 278 notifyItemMoved(from, to); 279 } 280 281 @Override 282 public int getItemCount() { 283 return mItems.size(); 284 } 285 } 286 287 288 } 289