0

にカスタムビューからコミュニケーション:アクティビティのレイアウトではが、私はこのようになります構造を有する活動

Activity -> Adapter -> Custom View 

を、私はEditTextを持っています。カスタムビューのレイアウトでは、私はButtonを持っています。ユーザーがカスタムビューのボタンをクリックすると、アクティビティ内のEditTextにフォーカスして、ユーザーがメッセージを入力できるようにする必要があります。

どうすればいいですか?ここで

は私の活動である:ここでは

public class MainActivity extends AppCompatActivity {  
    private List<City> cities; 

    private MyAdapter adapter; 

    private RecyclerView.LayoutManager layoutManager; 

    private RecyclerView recyclerView; 

    // The activity's EditText 
    private EditText editText; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     editText = (EditText) findViewById(R.id.editText); 

     recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
     recyclerView.setHasFixedSize(true); 

     mLayoutManager = new LinearLayoutManager(this); 

     recyclerView.setLayoutManager(layoutManager); 
     recyclerView.setItemAnimator(new DefaultItemAnimator()); 

     adapter = new MyAdapter(context, cities, true); 
     recyclerView.setAdapter(adapter); 
    } 
} 

は私のアダプタです:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { 
    private Context context; 

    private List<City> cities; 

    public MyAdapter(Context context, List<City> cities) { 
     this.context = context; 
     this.cities = cities; 
    } 

    public class ViewHolder extends RecyclerView.ViewHolder { 
     public City city; 

     public ViewHolder(CustomCityView itemView) { 
      super(itemView); 
     } 

     public void setCity(City city) { 
      ((CustomCityView) itemView).setCity(city); 
     } 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     CustomCityView customView = new CustomCityView(context); 

     return new ViewHolder(customView); 
    } 

    @Override 
    public void onBindViewHolder(final ViewHolder holder, int position) { 
     City city = cities.get(position); 

     holder.setCity(city); 
    } 

    @Override 
    public int getItemCount() { 
     return cities.size(); 
    } 
} 

そして最後に、ここに私のカスタムビュークラスです:

public class CustomCityView extends RelativeLayout { 
    private City city; 

    private TextView cityName; 

    // The button mentioned above 
    private Button button; 

    public CustomCityView(Context context) { 
     super(context); 
     init(); 
    } 

    public CustomCityView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

    private void init() { 
     LayoutInflater.from(getContext()).inflate(R.layout.custom_city_layout, this, true); 

     cityName = (TextView) findViewById(R.id.cityName); 
     button = (Button) findViewById(R.id.button); 
    } 

    public void setCity(final City city) { 
     this.city = city; 

     cityName.setText(city.getName()); 

     button.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       // If the user clicks on this button, how do I focus on the activity's EditText (and pass data to it)? 
      } 
     }); 
    } 
} 

そして、ここでは、カスタムですビューのレイアウト:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <TextView 
     android:id="@+id/cityName" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textSize="18sp" /> 

    <Button 
     android:id="@+id/button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

</RelativeLayout> 

質問は簡単です。ユーザーがカスタムビューのButtonをクリックした場合、ユーザーがメッセージを入力できるように、アクティビティのEditTextにどのようにフォーカスできますか?

さらに、アクティビティのEditTextに「ヒント」として表示するために、カスタムビュー(カスタムレイアウトの都市名など)からアクティビティにデータを渡すことは可能でしょうか? View.OnClickListenerと同じロジックに続い

+0

は、なぜあなたはあなたから行うことができないすべての 'CustomCityView'が必要なのか、コンテキストをキャストすることができます'ViewHolder'? –

+0

@ cricket_007複数の状況、異なるアダプタなどで 'CustomCityView'を使用します。なぜですか?私のやり方には欠点がありますか? – user7659189

+0

もう少し進んでいくクラス。 'CustomCityView'クラスにカスタムロジックがない場合は、通常のXMLファイルとLayoutInflaterを使用できます。 –

答えて

2

...

は、単にクリックするために、独自のインタフェースを定義します。

のは、あなたを呼んで、定期onClickに、そして、それCustomCityView.CityButtonClickListener

public class CustomCityView extends RelativeLayout 
    implements View.OnClickListener { 

    public interface CityButtonClickListener { 
     void onCityButtonClick(City city); 
    } 

    private CityButtonClickListener buttonClickListener; 

    public void setCityButtonClickListener(CityButtonClickListener listener) { 
     this.buttonClickListener = listener; 
    } 

    ... 

を呼ぶことにしましょう。

public class CustomCityView extends RelativeLayout 
    implements View.OnClickListener { 

    ... 

    @Override 
    public void onClick(View v) { 
     switch (v.getId()) { 
      case R.id.button: 
       if (buttonClickListener != null) { 
        buttonClickListener.onCityButtonClick(city); 
       } 
       break; 
      default: 
       break; 
     } 
    } 

    public void setCity(final City city) { 
     this.city = city; 

     cityName.setText(city.getName()); 

     button.setOnClickListener(this); 
    } 

アクティビティクラスのインターフェイスを実装してからアダプタ/ビューホールダーに渡します。言い換えれば

、あなたは

public void setCity(City city) { 
     CustomCityView cityView = (CustomCityView) itemView; 
     cityView.setCity(city); 
     try { 
      cityView.setCityButtonClickListener((CityButtonClickListener) context); 
     } catch (ClassCastException e) { 
      e.printStackTrace(); 
     } 
    } 

とバック活動中...

public class MainActivity extends AppCompatActivity 
    implements CustomCityView.CityButtonClickListener { 

    @Override 
    public void onCityButtonClick(City city) { 
     // TODO: Update EditText 
    } 
+0

私はこれに苦しんでいます。この "コールバック地獄/高結合"はAndroidの最高のプログラミングの慣行と考えられていますか?この問題のためのEventBusの実装も見てきました。 –

+0

インターフェイスの2つのレベルだけがコールバックhellではありません。また、インターフェース/「オブザーバーパターン」は非常に緩やかなカップリング –

関連する問題