Java 改变活动';从适配器中编辑文本->;自定义视图

Java 改变活动';从适配器中编辑文本->;自定义视图,java,android,android-activity,android-recyclerview,Java,Android,Android Activity,Android Recyclerview,基本上,我有这样的结构: 活动->回收视图适配器->自定义视图 下面是我的代码(为了更清楚,我省略了一些部分) 以下是我的活动MainActivity.java: public class MainActivity extends AppCompatActivity { private final String TAG = "MainActivity"; private EditText textField; @Override protected void

基本上,我有这样的结构:

活动->回收视图适配器->自定义视图

下面是我的代码(为了更清楚,我省略了一些部分)

以下是我的活动MainActivity.java:

public class MainActivity extends AppCompatActivity {

    private final String TAG = "MainActivity";

    private EditText textField;

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

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

        if (toolbar != null) {
            setSupportActionBar(toolbar);
        }

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

        // Adapter code
    }
}
这是我的适配器MyAdapter.java:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private static final String TAG = "MyAdapter";

    private Context context;

    public MyAdapter(Context context) {
        this.context = context;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View v) {
            super(v);
        }
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);

        CustomView customView = new CustomView(context);

        ViewHolder viewHolder = new ViewHolder(customView);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        //
    }

}
我希望能够做到的是,如果用户在自定义视图中单击
mPicture
,它应该将我的活动中编辑文本的文本更改为“Hello,world!”


如何执行此操作?

将您的文本字段从private更改为:

public static EditText textField;
在CustomView中,您现在应该能够设置文本:

mPicture.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            MainActivity.textField.setText("Hello World");
        }
    });

将文本字段从private更改为:

public static EditText textField;
在CustomView中,您现在应该能够设置文本:

mPicture.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            MainActivity.textField.setText("Hello World");
        }
    });
添加一个接口

public class CustomView extends RelativeLayout {

    public interface PictureClickListener {
        public void onPictureClick();
    }

    private PictureClickListener listener;

    public setPictureClickListener(PictureClickListener listener) {
        this.listener = listener
    }

    ...


        mPicture.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (CustomView.this.listener != null)
                    CustomView.this.listener.onPictureClick();
            }
        });
设置接口并实现它

public class MainActivity extends AppCompatActivity 
        implements PictureClickListener {

    @Override public void onPictureClick() {
        // change text of EditText in Activity here
    }

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

        // Apapter code
        adapter.setPictureClickListener(MainActivity.this);

}

注意:如果没有
CustomView
,这将更加容易。。。只需让
ViewHolder
充气
R.layout.item\u layout
,然后将界面移到那里

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(context);

    View v = inflater.inflate(....); // here

    ViewHolder viewHolder = new ViewHolder(v);
    return viewHolder;
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
    holder.mPicture.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (MyAdapter.this.listener != null)
                MyAdapter.this.listener.onPictureClick();
        }
    });
}
添加一个接口

public class CustomView extends RelativeLayout {

    public interface PictureClickListener {
        public void onPictureClick();
    }

    private PictureClickListener listener;

    public setPictureClickListener(PictureClickListener listener) {
        this.listener = listener
    }

    ...


        mPicture.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (CustomView.this.listener != null)
                    CustomView.this.listener.onPictureClick();
            }
        });
设置接口并实现它

public class MainActivity extends AppCompatActivity 
        implements PictureClickListener {

    @Override public void onPictureClick() {
        // change text of EditText in Activity here
    }

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

        // Apapter code
        adapter.setPictureClickListener(MainActivity.this);

}

注意:如果没有
CustomView
,这将更加容易。。。只需让
ViewHolder
充气
R.layout.item\u layout
,然后将界面移到那里

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(context);

    View v = inflater.inflate(....); // here

    ViewHolder viewHolder = new ViewHolder(v);
    return viewHolder;
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
    holder.mPicture.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (MyAdapter.this.listener != null)
                MyAdapter.this.listener.onPictureClick();
        }
    });
}

首先,您可以在
onCreateViewHolder
方法中膨胀自定义视图,而不是创建
CustomView
类。我的解决方案是将适配器更改为
抽象类
,并在适配器内创建一个新的
抽象
方法。您所要做的就是
覆盖活动中的
抽象方法

//change adapter to abstract class
public abstract class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private static final String TAG = "MyAdapter";
    List<String> list = new ArrayList<>(); //your data

    private Context context;

    public MyAdapter(Context context) {
        this.context = context;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);

        View customView = inflater.inflate(R.layout.item_layout, parent, false); //inflate the custom view

        ViewHolder viewHolder = new ViewHolder(customView);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
       ViewHolder body = (ViewHolder) holder;
       body.populateView(); //you can also pass some parameters here
    }

    @Override
    public int getItemCount() {
        return list.size(); //size of your array
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private RelativeLayout mLayout;
        private ImageView mPicture;

        public ViewHolder(View v) {
            super(v);
            this.mLayout = (RelativeLayout) v.findViewById(R.id.layout);
            this.mPicture = (ImageView) v.findViewById(R.id.picture);
        }

        public void populateView(){
            //set click listener to the picture
            this.mPicture.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    onPictureClick(); // call the abstract method
                }
            });
        }
    }

    //create new abstract method
    public abstract void onPictureClick();
}

首先,您可以在
onCreateViewHolder
方法中膨胀自定义视图,而不是创建
CustomView
类。我的解决方案是将适配器更改为
抽象类
,并在适配器内创建一个新的
抽象
方法。您所要做的就是
覆盖活动中的
抽象方法

//change adapter to abstract class
public abstract class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private static final String TAG = "MyAdapter";
    List<String> list = new ArrayList<>(); //your data

    private Context context;

    public MyAdapter(Context context) {
        this.context = context;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);

        View customView = inflater.inflate(R.layout.item_layout, parent, false); //inflate the custom view

        ViewHolder viewHolder = new ViewHolder(customView);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
       ViewHolder body = (ViewHolder) holder;
       body.populateView(); //you can also pass some parameters here
    }

    @Override
    public int getItemCount() {
        return list.size(); //size of your array
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private RelativeLayout mLayout;
        private ImageView mPicture;

        public ViewHolder(View v) {
            super(v);
            this.mLayout = (RelativeLayout) v.findViewById(R.id.layout);
            this.mPicture = (ImageView) v.findViewById(R.id.picture);
        }

        public void populateView(){
            //set click listener to the picture
            this.mPicture.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    onPictureClick(); // call the abstract method
                }
            });
        }
    }

    //create new abstract method
    public abstract void onPictureClick();
}

您是否尝试过“EditText=(EditText)context.findViewById(R.id.textField);”?在CustomView中,在创建新的CustomView时,保留对您要求的上下文的引用。稍后,我想创建它,以便它在不同的上下文/活动下执行不同的操作。因此,在一个活动中,我可能想更改EditText的文本,在另一个活动中,我可能想更改单击
mPicture
时屏幕上按钮的颜色。如何将
适配器更改为
抽象类
,并在
适配器
内创建一个新的
抽象方法
,单击
mPicture
时调用
abstract方法
,然后在活动内创建自己的实现。请检查我的答案。您尝试过“EditText=(EditText)context.findViewById(R.id.textField);”吗?在CustomView中,在创建新的CustomView时,保留对您要求的上下文的引用。稍后,我想创建它,以便它在不同的上下文/活动下执行不同的操作。因此,在一个活动中,我可能想更改EditText的文本,在另一个活动中,我可能想更改单击
mPicture
时屏幕上按钮的颜色。如何将
适配器更改为
抽象类
,并在
适配器
内创建一个新的
抽象方法
,单击
mPicture
时调用
abstract方法
,然后在活动内创建自己的实现。请检查我的答案。静态视图不好,会发生严重的内存泄漏。静态视图不好,会发生严重的内存泄漏。我按照你的建议,但侦听器似乎总是
null
,我不知道为什么。哦,对不起,我忘了使用
setPictureClickListener
。。。但是考虑到你有CustomView类,我真的不确定该把它放在哪里。我已经按照你的建议做了,但是侦听器似乎总是
null
,我不知道为什么。哦,对不起,我忘了使用
setPictureClickListener
。。。但考虑到你有那个CustomView课程,我真的不确定该把它放在哪里。正是我在找的。正是我在找的。