问题描述:

I have a listview where every item is textview and custom view. Here is layout of listview item:

<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 here is a custom view which draws a ruler and handles horizontal scrolling.

I want to pass same motion event to every item's ruler so that when i scroll one from the list others scroll simultaneously.

In adapter i set listener to custom view. Here is getView portion:

@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;

}

In Main Activity i find my list and set adapter to it.

Let's say i have 4 items in listview. But only 2 move simultaneously. What is a proper way to pass same motion event to all rulers in list?

网友答案:

if I understand, you want to make scroll all TimeScale if you scroll one of them. In this case I'd make a singletone manager class with a regsiter(TimeScale ts) method and a scrollAll() and unregisterAll() methods. In adapter getView() register the view to the manager, and when you scroll on a TimeScale call scrollAll() method too and when the list is destroyed call unregister all to delete Timescales references. But maybe it's better to register at view's onAttachToWindow() and unregister at onDetachFromWindow(). I don't know. In this case I would check this solution with LeakCanary doesn't it cause memory leaks. Other solution can be LocalBroadcastManager, but I don't know won't it cause performance issues.

网友答案:

Your adapter should implement an interface with a callback method, where you can pass the new value (or just add a public method to your adapter). Then pass the interface (or the adapter) to each view, and when you change the value you can call the callback method and pass the new value. In you adapter where you implemented this method you can loop trough your collection and set the new value by a setter method.

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);

}

相关阅读:
Top