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

只有两层深的接口不是回调地狱。另外,接口/“观察者模式”产生非常松散的耦合 –