在侦听器类

时间:2015-07-23 11:46:53

标签: android android-fragments android-context

我正在尝试为片段中的edittext实现和自动完成功能,但是无法将片段的上下文传递给listener / textwatcher。在构造函数中,它接受上下文作为参数,但在尝试将上下文链接到片段时会出现“无法转换的类型”错误。

`EmpAddFragment mainActivity = ((EmpAddFragment)context);`

下面是监听器的代码以及调用它的片段。

CustomAutoCompleteTextChangedListener.java:

import android.content.Context;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;

public class CustomAutoCompleteTextChangedListener implements TextWatcher {

public static final String TAG = "CustomAutoCompleteTextChangedListener.java";
Context context;
View view;
Fragment fragment;

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

@Override
public void afterTextChanged(Editable s) {
    // TODO Auto-generated method stub

}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
                              int after) {
    // TODO Auto-generated method stub

}

@Override
public void onTextChanged(CharSequence userInput, int start, int before, int count) {



    EmpAddFragment mainActivity = ((EmpAddFragment)context);

    // query the database based on the user input
    mainActivity.item = mainActivity.getItemsFromDb(userInput.toString());

    // update the adapater
    mainActivity.myAdapter.notifyDataSetChanged();
    mainActivity.myAdapter = new ArrayAdapter<String>(mainActivity.getActivity(), android.R.layout.simple_dropdown_item_1line, mainActivity.item);
    mainActivity.myAutoComplete.setAdapter(mainActivity.myAdapter);

   }

 }

EmpAddFragment:

import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.*;


public class EmpAddFragment extends Fragment implements OnClickListener      {

// UI references
private EditText empNameEtxt;
private Button addButton;
private Button resetButton;
/*
 * Change to type CustomAutoCompleteView instead of AutoCompleteTextView
 * since we are extending to customize the view and disable filter
 * The same with the XML view, type will be CustomAutoCompleteView
 */
CustomAutoCompleteView myAutoComplete;

// adapter for auto-complete
ArrayAdapter<String> myAdapter;

// for database operations
DataBaseHelper databaseH;

// just to add some initial value
String[] item = new String[] {"Please search..."};

private static final SimpleDateFormat formatter = new SimpleDateFormat(
        "yyyy-MM-dd", Locale.ENGLISH);

DatePickerDialog datePickerDialog;
Calendar dateCalendar;

Employee employee = null;
private EmployeeDAO employeeDAO;
private AddEmpTask task;

public static final String ARG_ITEM_ID = "emp_add_fragment";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    employeeDAO = new EmployeeDAO(getActivity());
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_add_emp, container,
            false);

    findViewsById(rootView);

    setListeners();

    try{

        // instantiate database handler
        databaseH = new DataBaseHelper(getActivity());


        // autocompletetextview is in activity_main.xml
        myAutoComplete = (CustomAutoCompleteView) rootView.findViewById(R.id.myautocomplete);

        // add the listener so it will tries to suggest while the user types
        myAutoComplete.addTextChangedListener(new CustomAutoCompleteTextChangedListener(this.getActivity()));

        // set our adapter
        myAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_dropdown_item_1line, item);
        myAutoComplete.setAdapter(myAdapter);

    } catch (NullPointerException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }

    //For orientation change.
    if (savedInstanceState != null) {
        dateCalendar = Calendar.getInstance();
        if (savedInstanceState.getLong("dateCalendar") != 0)
            dateCalendar.setTime(new Date(savedInstanceState
                    .getLong("dateCalendar")));
    }

    return rootView;


}

private void setListeners() {

    Calendar newCalendar = Calendar.getInstance();
    datePickerDialog = new DatePickerDialog(getActivity(),
            new OnDateSetListener() {

                public void onDateSet(DatePicker view, int year,
                                      int monthOfYear, int dayOfMonth) {
                    dateCalendar = Calendar.getInstance();
                    dateCalendar.set(year, monthOfYear, dayOfMonth);

                }

            }, newCalendar.get(Calendar.YEAR),
            newCalendar.get(Calendar.MONTH),
            newCalendar.get(Calendar.DAY_OF_MONTH));

    addButton.setOnClickListener(this);
    resetButton.setOnClickListener(this);
}

protected void resetAllFields() {
    empNameEtxt.setText("");

}

private void setEmployee() {
    employee = new Employee();
    employee.setName(empNameEtxt.getText().toString());

}

@Override
public void onResume() {
    getActivity().setTitle(R.string.add_emp);
    getActivity().getActionBar().setTitle(R.string.add_emp);
    super.onResume();
}

@Override
public void onSaveInstanceState(Bundle outState) {
    if (dateCalendar != null)
        outState.putLong("dateCalendar", dateCalendar.getTime().getTime());
}

private void findViewsById(View rootView) {
    empNameEtxt = (EditText) rootView.findViewById(R.id.etxt_name);


    addButton = (Button) rootView.findViewById(R.id.button_add);
    resetButton = (Button) rootView.findViewById(R.id.button_reset);
}

@Override
public void onClick(View view) {
    if (view == null) {

    } else if (view == addButton) {
        setEmployee();

        task = new AddEmpTask(getActivity());
        task.execute((Void) null);
    } else if (view == resetButton) {
        resetAllFields();
    }
}

public class AddEmpTask extends AsyncTask<Void, Void, Long> {

    private final WeakReference<Activity> activityWeakRef;

    public AddEmpTask(Activity context) {
        this.activityWeakRef = new WeakReference<Activity>(context);
    }

    @Override
    protected Long doInBackground(Void... arg0) {
        long result = employeeDAO.save(employee);
        return result;
    }

    @Override
    protected void onPostExecute(Long result) {
        if (activityWeakRef.get() != null
                && !activityWeakRef.get().isFinishing()) {
            if (result != -1)
                Toast.makeText(activityWeakRef.get(), "Employee Saved",
                        Toast.LENGTH_LONG).show();
        }

    }
}

// this function is used in CustomAutoCompleteTextChangedListener.java
public String[] getItemsFromDb(String searchTerm){

      // add items on the array dynamically
      List<MyObject> products = databaseH.read(searchTerm);
      int rowCount = products.size();

      String[] item = new String[rowCount];
      int x = 0;

      for (MyObject record : products) {

        item[x] = record.objectName;
        x++;
      }

       return item;
    }
 }

这是我使用时的logcat

 `EmpAddFragment mainActivity = new EmpAddFragment;

所有其他尝试输出无法转换的类型错误

logcat的:

07-23 06:49:17.828    2017-2017/com.example.autoFill E/AndroidRuntime﹕     FATAL EXCEPTION: main
Process: com.example.autoFill, PID: 2017
java.lang.NullPointerException
        at com.example.autoFill.EmpAddFragment.getItemsFromDb(EmpAddFragment.java:209)
        at com.example.autoFill.CustomAutoCompleteTextChangedListener.onTextChanged(CustomAutoCompleteTextChangedListener.java:42)
        at android.widget.TextView.sendOnTextChanged(TextView.java:7408)
        at android.widget.TextView.handleTextChanged(TextView.java:7467)
        at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:9187)
        at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:962)
        at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:496)
        at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:212)
        at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:30)
        at android.view.inputmethod.BaseInputConnection.deleteSurroundingText(BaseInputConnection.java:243)
        at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:382)
        at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5001)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
        at dalvik.system.NativeStart.main(Native Method)

更新:

将我的侦听器构造函数更改为:

 public CustomAutoCompleteTextChangedListener(EmpAddFragment frag){
    frag = fragment;
    context = fragment.getActivity();
 }

和致电:

 myAutoComplete.addTextChangedListener(new CustomAutoCompleteTextChangedListener(this));

但是在logcat中注册NullPointerException指向:

 myAutoComplete.addTextChangedListener(new CustomAutoCompleteTextChangedListener(this));

context = fragment.getActivity();

2 个答案:

答案 0 :(得分:0)

 myAutoComplete.addTextChangedListener(new CustomAutoCompleteTextChangedListener(this.getActivity()));

上面的行你没有传递片段,而是调用它的活动,所以当你打电话时:

EmpAddFragment mainActivity = ((EmpAddFragment)context);

它无法正常工作,因为您正在向EmpAddFragment转换为一个Activity实例。

所以如果你想让片段实例更改监听器构造函数并传递片段。 如果你想拥有活动,那么将上下文转换为活动

答案 1 :(得分:0)

更改侦听器类的构造函数

 public class CustomAutoCompleteTextChangedListener implements TextWatcher {

    public static final String TAG = "CustomAutoCompleteTextChangedListener.java";
    Context context;
    View view;
    Fragment fragment;

    public CustomAutoCompleteTextChangedListener(EmpAddFragment fragment){
        this.fragment = fragment;
        this.context = fragment.getActivity();
    }

    //.... rest of your listener class implementation
}

如果你面对&#34;不可转换的类型&#34;

,请按照以下方式使用调用方法
EmpAddFragment mainFragment = ((EmpAddFragment)fragment);

希望它有效!