我有一个列表视图,其中每个项目都是textview和自定义视图。这是listview项目的布局:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<net.manualuser.calibr.TimeScale
android:id="@+id/my_scale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingTop="40dp">
<TextView
android:id="@+id/counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
TimeScale是一个自定义视图,可以绘制标尺并处理水平滚动。
我想将相同的动作事件传递给每个项目的标尺,这样当我从列表中滚动一个时,其他项目同时滚动。
在适配器中,我将侦听器设置为自定义视图。这是getView部分:
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
View v = view;
if(view == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.time_scale_item, viewGroup, false);
}
scale = (TimeScale)v.findViewById(R.id.my_scale);
scale.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
scale.onTouchEvent(event);
return false;
}
});
TextView text = (TextView)v.findViewById(R.id.counter);
text.setText(Cities.get(i));
return v;
}
在主要活动中,我找到我的列表并设置适配器。 假设我在listview中有4个项目。但只有2个同时移动。将相同的运动事件传递给列表中的所有标尺的正确方法是什么?
答案 0 :(得分:0)
如果我理解,如果你滚动其中一个,你想要滚动所有TimeScale。 在这种情况下,我使用regsiter(TimeScale ts)方法和scrollAll()以及unregisterAll()方法创建单一管理器类。 在适配器中,getView()将视图注册到管理器,当您在TimeScale上滚动时也调用scrollAll()方法,当列表被销毁时,调用unregister all来删除Timescales引用。 但也许最好在观看onAttachToWindow()注册并注销atDetachFromWindow()。我不知道。 在这种情况下,我会检查这个解决方案与LeakCanary不会导致内存泄漏。 其他解决方案可以是LocalBroadcastManager,但我不知道它是否会导致性能问题。
答案 1 :(得分:0)
您的适配器应该使用回调方法实现一个接口,您可以在其中传递新值(或者只是向您的适配器添加一个公共方法)。然后将接口(或适配器)传递给每个视图,当您更改该值时,可以调用回调方法并传递新值。 在您实现此方法的适配器中,您可以循环收集集合并通过setter方法设置新值。
public class MyAdapter extends BaseAdapter implements OnValueChanged {
ArrayList<ListItem> listItems = new ArrayList<>();
public MyAdapter() {
super();
}
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
@Override
public void onValueChanged(int newValue) {
for (ListItem listItem : listItems) listItem.setValue(newValue);
}
class ListItem extends View implements View.OnClickListener {
private int value;
private OnValueChanged onValueChanged;
public ListItem(Context context, OnValueChanged onValueChanged) {
super(context);
this.onValueChanged = onValueChanged;
setOnClickListener(this);
}
public void setValue(int value) {
this.value = value;
}
@Override
public void onClick(View v) {
int newValue = 1;
onValueChanged.onValueChanged(newValue);
}
}
}
interface OnValueChanged {
void onValueChanged(int newValue);
}