Имеем ReciclerView
, на экране отображается список. Список обновляется каждые 5 сек. При нажатии на элемент списка, элемент расширяется (чтобы отобразить больше информации) или сужается обратно.
Проблема в том, что открытый элемент сужается из-за того, что таймер работает.
Мне нужно при расширении элемента остановить таймер(handler
или runnable
или как он там правильно называется), а при сужении снова запустить. Для этого я написал 2 метода в MainActivity
- startRepeatingTask()
и stopRepeatingTask()
, но не знаю как получить к ним доступ из класса ViewHolder
.
MainActivity.java
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
ConnectionItemAdapter adapter;
List<ConnectionItem> connectionItems;
Handler timerHandler;
Runnable timerRunnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InitRecyclerView();
timerHandler = new Handler();
timerRunnable = new Runnable() {
@Override
public void run() {
//тут обновляется адаптер
adapter.notifyDataSetChanged();
timerHandler.postDelayed(this, 5000); //каждые 5 секунд
}
};
timerHandler.postDelayed(timerRunnable, 5000);
}
void startRepeatingTask()
{
timerRunnable.run();
}
void stopRepeatingTask()
{
timerHandler.removeCallbacks(timerRunnable);
}
}
ViewHolder.java
public class ConnectionItemsAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private boolean isViewExpanded = false;
private int originalHeight = 0;
public ConnectionItemsAdapterViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
fcuName = (TextView)itemView.findViewById(R.id.FcuName);
branchName = (TextView) itemView.findViewById(R.id.FcuBranchName);
result = (TextView) itemView.findViewById(R.id.ResultText);
versionIcon = (ImageView) itemView.findViewById(R.id.versionIcon);
// If isViewExpanded == false then set the visibility
// of whatever will be in the expanded to GONE
if (isViewExpanded == false) {
// Set Views to View.GONE and .setEnabled(false)
branchName.setVisibility(View.GONE);
branchName.setEnabled(false);
}
}
public TextView fcuName;
public TextView branchName;
public ImageView versionIcon;
public TextView result;
@Override
public void onClick(final View view) {
// If the originalHeight is 0 then find the height of the View being used
// This would be the height of the cardview
if (originalHeight == 0) {
originalHeight = view.getHeight();
}
// Declare a ValueAnimator object
ValueAnimator valueAnimator;
if (!isViewExpanded) {
branchName.setVisibility(View.VISIBLE);
branchName.setEnabled(true);
isViewExpanded = true;
// Вот где-то тут надо остановить таймер
valueAnimator = ValueAnimator.ofInt(originalHeight, originalHeight + (int) (originalHeight * 2.0)); // These values in this method can be changed to expand however much you like
} else {
isViewExpanded = false;
valueAnimator = ValueAnimator.ofInt(originalHeight + (int) (originalHeight * 2.0), originalHeight);
Animation a = new AlphaAnimation(1.00f, 0.00f); // Fade out
a.setDuration(200);
// Set a listener to the animation and configure onAnimationEnd
a.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
branchName.setVisibility(View.INVISIBLE);
branchName.setEnabled(false);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
// Set the animation on the custom view
branchName.startAnimation(a);
}
valueAnimator.setDuration(200);
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
view.getLayoutParams().height = value.intValue();
view.requestLayout();
}
});
valueAnimator.start();
}
}
Только начал изучать android и java, возможно кто-то подскажет более правильный подход.
Правильный способ - прокинуть интерфейс через адаптер во ViewHolder.
public interface MyInterface {
void onClick();
}
public class MyAdapter extends .... {
private MyInterface mMyInterface;
public MyAdapter(MyInterface myInterface) {
mMyInterface = myInterface;
}
}
public class ConnectionItemsAdapterViewHolder extends RecyclerView.ViewHolder {
private MyInterface mMyInterface;
public ConnectionItemsAdapterViewHolder(View itemView, MyInterface mMyInterface) {
super(itemView);
mMyInterface = myInterface;
}
}
@Override
public void onClick(final View view) {
mMyInterface.onClick();
}
MyAdapter adapter = new MyAdapter(new MyInterface(){
@Override
public void onClick(){
startRepeatingTask();
}
})
А самый простой способ - кастануть контекст к активити как-то так:
//в классе ViewHolder
((MainActivity)itemView.getContext()).startRepeatingTask();
Все очень скучно и муторно:
RecyclerView
в конструктор адаптера засылаем ссылку на ваш Activity
ViewHolder
также в конструкторе засылаем из адаптера ссылку на Activity
Activity
- в нужном месте вызываем методы Activity
Можно конечно реализовать идеологически выдержанный и православный паттерн через интерфейсы, но овчинка вряд ли стоит выделки.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
У меня есть List<Document> listOfDocuments = new ArrayList<>() объектов
Есть таблица c полем descriptionКак мне сделать поиск в таблице по этому полю так, чтоб выводились не только записи в которых description полностью совпадает...
Какой элемент нужно использовать для вывода информации пользователю? TextField использую в настоящее время, но он не подходит, так как позволяет...