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中的「提示」?

+0

爲什麼你需要'CustomCityView'可言,你不能從做'ViewHolder'? –

+0

@ cricket_007我在多種情況下,在不同的適配器等中使用'CustomCityView'爲什麼?按照我的方式行事有缺點嗎? – user7659189

+0

只需要更多的課程。如果您在CustomCityView類中沒有自定義邏輯,則可以使用常規XML文件和LayoutInflater。 –

回答

2

按照同樣的邏輯,View.OnClickListener ......

簡單地定義自己的界面點擊。

我們稱之爲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; 
    } 

    ... 

然後,在常規onClick,叫你的。

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

然後,您將實現Activity類的接口傳遞給Adapter/ViewHolder。

換句話說,你可以投背景

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

只有兩層深的接口不是回調地獄。另外,接口/「觀察者模式」產生非常鬆散的耦合 –