简体   繁体   English

如何从另一个类及其上下文中调用函数(Android,Java)

[英]How to call a function from another class with its context (android, java)

I'm trying to reload a viewPager whenever the user pushes a button inside an Item from the viewPager. 每当用户在viewPager中的Item内按下按钮时,我都试图重新加载viewPager。 The relevant classes for this case are SetupActivity and Adapter . 这种情况下的相关类是SetupActivityAdapter In the activity class I've already made the two functions to reload the viewPager: 在活动类中,我已经制作了两个函数来重新加载viewPager:

public void deleteSession(String title) {
        dbHelper = new DatabaseHelper(this);
        ((DatabaseHelper) dbHelper).deleteRow(title);
    }

and

public void refreshAdapter () {

        dbHelper = new DatabaseHelper(this); 
        Cursor dataCursor = ((DatabaseHelper) dbHelper).getData();
        models = new ArrayList<>(); 

        while (dataCursor.moveToNext()) { 
            models.add(new Model(
                    dataCursor.getString(1),
                    dataCursor.getInt(2),
                    dataCursor.getInt(3),
                    dataCursor.getInt(4)
            ));
        }
        adapter = new Adapter(models, this);
        viewPager.setAdapter(adapter);
        viewPager.setCurrentItem(0, true);
    }

So basically, deleteSession() deletes a specific item from a database. 因此,基本上, deleteSession()从数据库中删除特定项目。 refreshAdapter() reads the updated data from the database and sets a new adapter to the viewPager. refreshAdapter()从数据库中读取更新的数据,并将新的适配器设置为viewPager。 These functions are working fine, if I call them from an OnClick event in the SetupActivity class. 如果我从SetupActivity类的OnClick事件中调用它们,这些函数将正常工作。 However, if I try to call them from an OnClick event in the Adapter class, the app crashes with the following errors: 但是,如果我尝试从Adapter类的OnClick事件中调用它们,则应用程序将崩溃,并出现以下错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getDatabasePath(java.lang.String)' on a null object reference
        at android.content.ContextWrapper.getDatabasePath(ContextWrapper.java:327)
        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:352)
        at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:322)
        at com.example.android.slink.DatabaseHelper.getData(DatabaseHelper.java:69)
        at com.example.android.slink.SetupActivity.refreshAdapter(SetupActivity.java:436)
        at com.example.android.slink.Adapter$3.onClick(Adapter.java:111)
        at android.view.View.performClick(View.java:6669)
        at android.view.View.performClickInternal(View.java:6638)
        at android.view.View.access$3100(View.java:789)
        at android.view.View$PerformClick.run(View.java:26145)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6863)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Here's my SetupActiviy class (reduced to the relevant parts): 这是我的SetupActiviy类(简化为相关部分):

package com.example.android.slink;

public class SetupActivity extends AppCompatActivity {

    private SQLiteOpenHelper dbHelper;
    private SQLiteDatabase database;

    ViewPager viewPager;
    Adapter adapter;
    static ArrayList<Model> models;

    public void deleteSession(String title) {
        dbHelper = new DatabaseHelper(this);
        ((DatabaseHelper) dbHelper).deleteRow(title);
    }

    public void refreshAdapter () {
        dbHelper = new DatabaseHelper(this);
        Cursor dataCursor = ((DatabaseHelper) dbHelper).getData();
        models = new ArrayList<>();
        models.add(new Model("", 0,0,0));
        while (dataCursor.moveToNext()) {
            models.add(new Model(
                    dataCursor.getString(1),
                    dataCursor.getInt(2),
                    dataCursor.getInt(3),
                    dataCursor.getInt(4)
            ));
        }
        adapter = new Adapter(models, this);
        viewPager.setAdapter(adapter);
        viewPager.setCurrentItem(0, true);
    }

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

        editTextScreenTitle = findViewById(R.id.editTextScreenTitle);
        relativeLayoutCard = findViewById(R.id.relativeLayoutCard);
        viewPager = findViewById(R.id.viewPager);

        dbHelper = new DatabaseHelper(this);
        Cursor dataCursor = ((DatabaseHelper) dbHelper).getData();

        models = new ArrayList<>();
        models.add(new Model("", 0,0,0));
        while (dataCursor.moveToNext()) {
            models.add(new Model(
                    dataCursor.getString(1),
                    dataCursor.getInt(2),
                    dataCursor.getInt(3),
                    dataCursor.getInt(4)
            ));
        }
        adapter = new Adapter(models, this);
        viewPager.setAdapter(adapter);
    }
}

Here's my Adapter class (also reduced to the relevant parts): 这是我的Adapter类(也简化为相关部分):

package com.example.android.slink;

public class Adapter extends PagerAdapter {

    private List<Model> models;
    private LayoutInflater layoutInflater;
    private Context context;

    SetupActivity setupActivity = new SetupActivity();

    public Adapter(List<Model> models, Context context) {
        this.models = models;
        this.context = context;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull final ViewGroup container, final int position) {
        layoutInflater = LayoutInflater.from(context);
        final View view = layoutInflater.inflate(R.layout.item, container, false);

        TextView buttonDeleteCard = view.findViewById(R.id.textViewDeleteCard);

        buttonDeleteCard.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setupActivity.deleteSession([...some title...]);
                setupActivity.refreshAdapter();
            }
        });

        container.addView(view, 0);
        return view;
    }
}

I think it has something to do whith the context. 我认为这与上下文有关。 Do I have to pass the context from SetupActiity to the Adapter class and if so, how do I do that? 我是否必须将上下文从SetupActiity传递给Adapter类,如果是,该怎么做? Or is it not possible and I need to catch the OnClick event in the Adapter class from in the SetupActivity class? 还是不可能,我需要从SetupActivity类的Adapter类中捕获OnClick事件? I'm new to java programming and would be very grateful if any of you could help me, solve this problem! 我是Java编程的新手,如果您能帮助我解决此问题,将不胜感激!

Change your Adapter like this: 像这样更改您的Adapter

public class Adapter extends PagerAdapter {

    private List<Model> models;
    private LayoutInflater layoutInflater;
    private Context context;

    private SetupActivity setupActivity;

    public Adapter(List<Model> models, Context context) {
        this.models = models;
        this.context = context;
        setupActivity = (SetupActivity) context;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull final ViewGroup container, final int position) {
        layoutInflater = LayoutInflater.from(context);
        final View view = layoutInflater.inflate(R.layout.item, container, false);

        TextView buttonDeleteCard = view.findViewById(R.id.textViewDeleteCard);

        buttonDeleteCard.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setupActivity.deleteSession([...some title...]);
                setupActivity.refreshAdapter();
            }
        });

        container.addView(view, 0);
        return view;
    }
}

Why the error? 为什么会出错?

You pass the Context from SetupActivity to your Adapter , you save that reference in the field ( context ) but you mistakenly created a new instance of SetupActivity . 您将ContextSetupActivity到您的Adapter ,将该引用保存在字段( context )中,但是您错误地创建了SetupActivity的新实例。

That's why you got the NullPointerException . 这就是为什么您得到NullPointerException的原因。 The activity is your Context . 活动是您的Context It inherits from it. 它继承自它。 So just cast it in your constructor and use it later. 因此,只需将其转换为构造函数,然后再使用即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM