2016-11-16 28 views
0

我有一個列表視圖,其中每個項目是textview和自定義視圖。這裏是ListView項的佈局:如何將同一個動作事件傳遞給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> 

時間表這裏是繪製一個統治者和處理水平滾動的自定義視圖。

我想將相同的動作事件傳遞給每個項目的標尺,以便當我從列表中滾動一個時,其他人同時滾動。

在適配器中,我將偵聽器設置爲自定義視圖。這裏是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; 
} 

在主要活動中找到我的列表,並設置適配器給它。 比方說,我有4個項目在列表視圖。但只有2個同時移動。將相同的運動事件傳遞給列表中的所有統治者的正確方法是什麼?

+0

它的工作原理部分。在兩個項目的列表中,當我滾動第一個時,第二個也移動,但不是相反,就好像在第二個視圖上沒有設置ontouchlistener一樣。但是,當列表中有三個項目時,它們會成對滾動:一個,三個,兩個,最後一個僅滾動自己。 –

回答

0

如果我明白了,你想滾動所有TimeScale,如果你滾動其中的一個。 在這種情況下,我會用regsiter(TimeScale ts)方法和scrollAll()和unregisterAll()方法創建一個singletone管理器類。 在適配器中,getView()向管理器註冊視圖,當您在TimeScale上調用scrollAll()方法時,當列表被銷燬時,調用註銷全部以刪除Timescales引用。 但是,最好在view的onAttachToWindow()上註冊並在onDetachFromWindow()註銷。我不知道。 在這種情況下,我會檢查這個解決方案與LeakCanary不會導致內存泄漏。 其他解決方案可以是LocalBroadcastManager,但我不知道它會不會導致性能問題。

+0

thx但有點複雜。我現在想找到適配器實現的解決方案。 –

+0

我明白了。也許你可以在變更其中一個適配器元素的列表時循環適配器元素,並在所有元素上設置相同的值。 – user3057944

+0

這就是我想要做的,但我不知道如何從列表中獲得acccess特定的小部件。我簡化了我的任務:讓我說我有一個包含textview的兩個項目的列表。當我點擊一個textview都改變文本。當然,我可以在getview:text.settext中的onclick方法中更改單擊textview的文本。但是,如何從另一個項目訪問textview? –

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

}

相關問題