2016-11-16 6 views
0

모든 항목이 텍스트보기 및 사용자 정의보기 인 목록보기가 있습니다.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; 
} 

내 활동 목록에서 내 목록을 찾아 어댑터를 설정합니다. listview에 4 개의 항목이 있다고 가정 해 보겠습니다. 그러나 2 개만 동시에 움직입니다. 동일한 모션 이벤트를 모든 통치자에게 전달하는 적절한 방법은 무엇입니까?

+0

이 부분적으로 작동합니다. 두 항목의 목록에서 두 번째보기에도 ontouchlistener가 설정되어 있지 않은 것처럼 첫 번째 항목을 스크롤하면 두 번째 항목이 움직이지만 반대로는 표시되지 않습니다. 그러나 목록에 세 개의 항목이있는 경우 한 쌍, 세 쌍, 세 쌍, 한 번만 스크롤 할 수 있습니다. –

답변

0

만약 내가 이해한다면, 당신은 그들 중 하나를 스크롤하면 모든 TimeScale을 스크롤하고 싶습니다. 이 경우에는 regsiter (TimeScale ts) 메서드와 scrollAll() 및 unregisterAll() 메서드를 사용하여 singletone 관리자 클래스를 만들 수 있습니다. 어댑터 getView()에서 뷰를 관리자에 등록하고 TimeScale 호출 scrollAll() 메서드를 스크롤 할 때 및 목록이 소멸되면 all을 등록 취소하여 시간 척도 참조를 삭제합니다. 하지만보기의 onAttachToWindow()에서 등록하고 onDetachFromWindow()에서 등록 취소하는 것이 더 나을 것입니다. 나는 모른다. 이 경우 LeakCanary로이 솔루션을 확인하면 메모리 누수가 발생하지 않습니다. 다른 솔루션은 LocalBroadcastManager가 될 수 있지만 성능 문제를 일으키지는 모르겠습니다.

+0

하지만 조금 복잡합니다. 지금은 어댑터에 구현할 솔루션을 찾고 싶습니다. 봐, –

+0

. 어쩌면 하나의 값을 변경하고 모든 요소에서 같은 값을 설정할 때 어댑터 요소 목록을 반복 할 수 있습니다. – user3057944

+0

그게 내가하고 싶은 일이지만 목록에서 특정 위젯에 어떻게 접근 할 수 있는지 모르겠습니다. 나는 나의 작업을 단순화했다 : 나는 textview와 함께 두 개의 항목이있는 목록을 가지고 있다고 말한다. 하나의 텍스트 뷰를 클릭하면 텍스트가 모두 변경됩니다. 물론 getview에서 onclick 메서드로 클릭 한 textview의 텍스트를 변경할 수 있습니다 : text.settext. 하지만 다른 항목에서 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); 

은}