android - 如何从 fragment 列表中的 EditText 获取用户输入?

标签 android listview android-fragments

我的代码的结构使得“抽屉 Activity ” 调用多个 fragment 抽屉之一,每个 fragment 抽屉包含一个 fragment 项目列表,这些 fragment 项目使用 ItemAdapter创建 fragment 列表。

我的主要问题是我一直在尝试检索 EditTextafterTextChanged()在项目适配器中,但总是得到 NullPointerException我希望能够检索用户刚刚输入的值。

非常感谢以文明方式提出的任何和所有建议。

抽屉 Activity

public class Drawers extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
public static boolean isSealBroken;
public static int DrawerChosen;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    System.out.println(savedInstanceState);
    setContentView(R.layout.activity_drawers);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);



    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction ft = fragmentManager.beginTransaction();
    ft.replace(R.id.screen_area, new drawer_top_Fragment());
    ft.commit();
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.drawers, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}


@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    Fragment fragment = null;

    int id = item.getItemId();
    //Find ID for buttons in Drawers Navigation bar and connect it to the correct fragment
    if (id == R.id.nav_drawer_top) {
        fragment = new drawer_top_Fragment();
    } else if (id == R.id.nav_drawer_med) {
        if (isSealBroken == false) {
            isSealBroken_Message();
        }
        if (isSealBroken == true) {
                fragment = new drawer_med_Fragment();
                DrawerChosen=1;
        }
    }
    else if(id == R.id.nav_drawer1) {
                if(isSealBroken==false){
                    isSealBroken_Message();
                     if(isSealBroken==true){
                         fragment = new drawer1_Fragment();
                         DrawerChosen=2;
                     }
                }else {
                    fragment = new drawer1_Fragment();
                    DrawerChosen=2;
                }
    }
    else if(id == R.id.nav_drawer2) {
                if(isSealBroken==false){
                    isSealBroken_Message();

                    if(isSealBroken==true){
                        fragment = new drawer2_Fragment();
                        DrawerChosen=3;
                    }
                }else {
                    fragment = new drawer2_Fragment();
                    DrawerChosen=3;
                }
    }
    // more of the same until nav 8
    else if(id == R.id.nav_drawer8) {
                if(isSealBroken==false){
                    isSealBroken_Message();
                    if(isSealBroken==true){
                        fragment = new drawer8_Fragment();
                        DrawerChosen=9;
                    }
                }else {
                    fragment = new drawer8_Fragment();
                    DrawerChosen=9;
                }
    }

    else if (id == R.id.drawer_continue) {
        final Intent intent = new Intent(this, WagonSummary.class);
        new AlertDialog.Builder(this)
                .setTitle("Er Skráningu hluta á vagni lokið?")
                .setNegativeButton("Nei",null)
                .setPositiveButton("já",new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                      //  FinishComputeList(); // calls upon class to compute value from list
                        startActivity(intent);
                    }
                }).create().show();

    } else if (id == R.id.drawer_comment) {
        Intent intent = new Intent(this, CommentSummary.class);
        startActivity(intent);
    }

    if(fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction ft = fragmentManager.beginTransaction();
        ft.replace(R.id.screen_area, fragment);
        ft.commit();
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

public void isSealBroken_Message()
{
    new AlertDialog.Builder(this)
            .setTitle("Er innsigli rofið?")
            .setNegativeButton("Nei",null)
            .setPositiveButton("já",new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    isSealBroken=true;
                    ListProcessing d = new ListProcessing();
                    d.sealBroken();
                }
}).create().show();
}

}

以其中一个抽屉 fragment 为例

public class drawer3_Fragment extends Fragment {

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

    getActivity().setTitle(R.string.drawer_three);

    ArrayList<Item> items = new ArrayList<Item>();

    String[] itemArr = getResources().getStringArray(R.array.drawer_three_items);
    int[] quantityArr = getResources().getIntArray(R.array.drawer_three_quantity);
    String[] typeArr = getResources().getStringArray(R.array.drawer_three_type);
    String item;
    int quantity;
    String type;

    for (int i = 0; i < itemArr.length; i++) {
        item = itemArr[i];
        quantity = quantityArr[i];
        type = typeArr[i];
        items.add(new Item(item, quantity, type));
    }

    ItemAdapter adapter = new ItemAdapter(getActivity(), items);

    ListView listView = (ListView) rootView.findViewById(R.id.list);

    listView.setAdapter(adapter);

    return rootView;
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
}
}

元素适配器

public class ItemAdapter extends ArrayAdapter<Item> {

public ItemAdapter(Activity context, ArrayList<Item> items) {

    super(context, 0, items);
}

@Override
public View getView(final int position, final View convertView, final ViewGroup parent){
    // Check if the existing view is being reused, otherwise inflate the view
    View listItemView = convertView;

    if(listItemView == null) {
        listItemView = LayoutInflater.from(getContext()).inflate(
                R.layout.list_item, parent, false);
    }


    // Get the {@link Item} object located at this position in the list
    final Item currentItem = getItem(position);
    final Item currentposs = getItem(position);

    // Find the TextView in the list_item.xml layout with the ID version_name
    TextView itemTextView = (TextView) listItemView.findViewById(R.id.item);

    // Get the version name from the current object and
    // set this text on the name TextView
    itemTextView.setText(currentItem.getItem());

    TextView infoTextView = (TextView) listItemView.findViewById(R.id.info);
    infoTextView.setText(currentItem.getInfo());

    TextView doseTextView = (TextView) listItemView.findViewById(R.id.dose);
    doseTextView.setText(currentItem.getDose());

    TextView quantityTextView = (TextView) listItemView.findViewById(R.id.quantity);
    quantityTextView.setText(currentItem.getQuantity());

    TextView typeTextView = (TextView) listItemView.findViewById(R.id.type);
    typeTextView.setText(currentItem.getType());

    CheckBox check = listItemView.findViewById(R.id.checkbox);


    //reset and Populating list
    final String itemName= currentposs.getItem();
    String itemInfo = currentposs.getInfo();
    String itemDose = currentposs.getDose();
    String itemQuantity = currentposs.getQuantity();
    String itemType = currentposs.getType();
   // populateList(position,itemName,itemInfo,itemDose,itemQuantity,itemType);
final View listItemView1 = listItemView;

    // when chekbox is ticked then list is amended
    check.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                    CheckBox checkBox = (CheckBox) v;
                    if (checkBox.isChecked()) {
                        // to see if correct location is beaing chosen each time
                        System.out.println("currentposs : "+currentposs);
                        System.out.println("position : "+position);
                        System.out.println("Parent : "+parent);
                        String itemName= currentposs.getItem();
                        System.out.println("getItem() : "+itemName);
                        String itemInfo = currentposs.getInfo();
                        System.out.println("getInfo() : "+ itemInfo);
                        String itemDose = currentposs.getDose();
                        System.out.println("getDose() : "+ itemDose);
                        String itemType = currentposs.getType();
                        System.out.println("getType() : "+ itemType);
                        String itemQuantity = currentposs.getQuantity();
                        System.out.println("getQuantity() : "+ itemQuantity);
                        int wagonNr = 0;
                        String status = "false";
                        ListProcessing d = new ListProcessing();
                       d.itemStatusChange( wagonNr,Drawers.DrawerChosen,position,status);
                    }
                }
        });
    //TextView.setContentView(R.layout.list_item);
    //String yourEditText = (EditText) currentposs.findViewById(R.id.quantity);

    final View finalListItemView = listItemView;
    quantityTextView.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            //nothing has worked
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        //nothing has worked
        }

        @Override
        public void afterTextChanged(Editable s) {
            //nothing has worked but here are some exaples of what i have tried   
//TextView quantityTextViewEdited = (TextView) convertView.findViewById(R.id.quantity);
          // String n = (String) currentItem.getText();

           // View listItemView2 = convertView;
           // EditText name=(EditText)listItemView2.findViewById(R.id.quantity);
         //   String a=name.getText().toString().trim();
          //  
         View listItemView2 = listItemView1;
            TextView quantityTextView2 = (TextView) listItemView2.findViewById(R.id.quantity);
          int numberInserted =  Log.e("input text", quantityTextView2.getText().toString());
            System.out.println("Changed qunatity: "+ numberInserted);

        }
    });


    if (currentItem.isCheckBox()) {
        check.setVisibility(View.VISIBLE);
        } else {
        check.setVisibility(View.GONE);
        }

    if (currentItem.isInfo()) {
        infoTextView.setVisibility(View.VISIBLE);
        } else {
        infoTextView.setVisibility(View.GONE);
        }

    if (currentItem.isDose()) {
        doseTextView.setVisibility(View.VISIBLE);
        } else {
        doseTextView.setVisibility(View.GONE);
        }

    if (currentItem.isQuantity()) {
        quantityTextView.setVisibility(View.VISIBLE);
        } else {
        quantityTextView.setVisibility(View.GONE);
        }

    return listItemView;
}

元素

public class Item {

private String item;
private String info;
private String dose;
private String type;
private int quantity;

private boolean isInfo = false;
private boolean isDose = false;
private boolean isQuantity = false;
private boolean isCheckBox = false;

/**
 * @param wItem
 */

public Item(String wItem) {
    item = wItem;
    isCheckBox = true;
}


/**
 * @param wItem is the name of the item/medicine
 * @param wQuantity is how many items there should be total
 * @param wType ...
 */
public Item(String wItem, int wQuantity, String wType) {
    item = wItem;
    quantity = wQuantity;
    type = wType;
    isCheckBox = true;
    isQuantity = true;
}

public Item(String wItem, String wInfo, String wDose, int wQuantity, String wType) {
    item = wItem;
    info = wInfo;
    dose = wDose;
    quantity = wQuantity;
    type = wType;
    isCheckBox = true;
    isQuantity = true;
    isDose = true;
    isInfo = true;
}

public String getItem() {
    return item;
}

public String getInfo() {
    return info;
}

public String getDose() {
    return dose;
}

public String getType() {
    return type;
}

public String getQuantity() {
    return Integer.toString(quantity);
}

public boolean isCheckBox() {
    return isCheckBox;
}

public boolean isInfo() {
    return isInfo;
}

public boolean isDose() {
    return isDose;
}

public boolean isQuantity() {
    return isQuantity;
}

public void findViewById (int quantity) {
}

更新 输入后 Log.e("input text", quantityTextView2.getText().toString());当用户输入新数字时,在“afterTextChanged”内,然后在终端中打印正确的用户输入。当试图将其封装在一个 int 变量中时,它只会返回数字 14,无论用户输入如何。

来自运行终端的例子

D/InputMethodManager: SSI - flag : 0 Pid : 16988 view : com.example.notandi.hospitalwagons
D/ViewRootImpl@be26588[PopupWindow:b7449a5]: Relayout returned: old=[622,841][712,949] new=[655,841][745,949] result=0x1 surface={valid=true 493809848320} changed=false
D/ViewRootImpl@3142bca[Drawers]: ViewPostIme key 0
I/System.out: !!!!!!!!!!!!!!!!!!!!!!afterTextChanged!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
I/System.out: Changed qunatity: 13
I/System.out: !!!!!!!!!!!!!!!!!!!!!!afterTextChanged!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
I/System.out: Changed qunatity: 13
D/ViewRootImpl@3142bca[Drawers]: ViewPostIme key 1
D/OpenGLRenderer: eglDestroySurface = 0x73093dc320
D/ViewRootImpl@be26588[PopupWindow:b7449a5]: dispatchDetachedFromWindow
D/InputEventReceiver: channel '9bf6f1 PopupWindow:b7449a5 (client)' ~ Disposing input event receiver.
D/InputEventReceiver: channel '9bf6f1 PopupWindow:b7449a5 (client)' ~NativeInputEventReceiver.
I/System.out: !!!!!!!!!!!!!!!!!!!!!!afterTextChanged!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
E/input text: 2
I/System.out: Changed qunatity: 14
I/System.out: !!!!!!!!!!!!!!!!!!!!!!afterTextChanged!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
E/input text: 2
I/System.out: Changed qunatity: 14

更新 2

它活了!! 由于用户 Nirav Bhavsar 的有用推荐,我探索了控制台日志方法并将以下代码插入到“onTextChanged”中

   String numberInserted ;
            final View listItemView2 = listItemView1;
            final TextView quantityTextView2 = (TextView) listItemView2.findViewById(R.id.quantity);
            String userinput = quantityTextView2.getText().toString();
            System.out.println("user input: "+userinput);

它有效,我能够检索用户插入的 EditText 值。非常感谢堆栈溢出社区。

最佳答案

I want to be able to retrieve the value that the user has just put in

给你,

 final View finalListItemView = listItemView;
 quantityTextView.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        //nothing has worked
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
     //here "s" is the latest text
    Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
    }

    @Override
    public void afterTextChanged(Editable s) {
     //don't do anything here, instead
     //get the  lastest text in onTextChanged()
    }
});

现在,为什么会出现 NullPointerException

因为你必须在 listItemView 中找到 View R.id.quantity 而不是在 convertViewlistItemView2afterTextChanged()

 //e.g
 EditText name=(EditText)listItemView2.findViewById(R.id.quantity);

此外,我想知道为什么不制作 quantityTextView final 并在 afterTextChanged() 中使用?

关于android - 如何从 fragment 列表中的 EditText 获取用户输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51751222/

相关文章:

java - Android 服务和 "alert window"

android - 自定义 android.R.layout.simple_list_item_checked

android - Activity 中的后退按钮无需重新创建先前的 Activity (Android)

java - Fragment运行时异常调试

android - 了解 ImageProcessing 代码

android - 在 LibGdx 中滚动主屏幕

java - 使用 SQLite (android) 存储数据的问题

c# - .Net 中的同步 ListView

java - 将 sqlite 数据从 ListView 传递到其他 Activity

android - FragmentTabHost 选项卡的内容未出现