2016-11-17 35 views
5

Uczę się prototypowania w Android Studio i dotarłem do przeszkody, na którą nie mogę znaleźć odpowiedzi.Dodanie do fragmentu ArrayAdapter z Activity AlertDialog

Mam działanie, które wyświetla niestandardowy ArrayAdapter jako ListView. Mogę edytować elementy w ListView, klikając je i wpisując w wynik AlertDialog. Jest też przycisk dodawania, który mogę nacisnąć, i wywołuje podobny AlertDialog, ale kiedy klikam, nic nie zostanie dodane do ListView. Jak uzyskać dane wejściowe tekstu AlertDialog do zapisania jako nowy element ArrayAdapter?

Większość znalezionych przeze mnie przykładów utworzyło ArrayAdapter bezpośrednio w Aktywności, a nie w Fragmentie tak, jak to zrobiłem.

MainActivity.java

public class MainActivity extends AppCompatActivity { 

private static final String TAG = "MainActivity"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { //initialize the activity 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); //establish where the layout will come from 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); //creates a toolbar 
    setSupportActionBar(toolbar); 

    if (findViewById(R.id.fragment_container) != null) { 
     if (savedInstanceState != null) { 
      return; 
     } 
     //creates the first fragment dynamically, so it can be replaced 
     Fragment firstFragment = new MainActivityFragment(); 
     firstFragment.setArguments(getIntent().getExtras()); 
     getSupportFragmentManager().beginTransaction() 
       .add(R.id.fragment_container, firstFragment).commit(); 
    } 

    //This creates the Floating Action Button 
    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
    fab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      createDialog(); 
     } 

     private void createDialog() { 
      ArrayList<User> users = new ArrayList<User>(); 

      // create an AlertDialog that'll come up when the add button is clicked 
      AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this); 

      // set title 
      alertDialog.setTitle("Add item"); 

      final EditText input = new EditText(MainActivity.this); //uses the EditText from dialog_set 
      input.setInputType(InputType.TYPE_CLASS_TEXT); //makes the dialog ask for plain text input 
      alertDialog.setView(input); 

      // set up buttons 

      alertDialog.setPositiveButton("Save", new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        String textInput = input.getText().toString(); //saves user text as a string 
        Log.d(TAG, textInput); // records input as a log 
        CustomUsersAdapter.this.add(textInput); 
       } 
      }); 

      alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
       } 
      }); 

      // show it 
      alertDialog.show(); 
     } 
    }); 
} 

MainActivityFragment.java

public class MainActivityFragment extends Fragment { 

@BindView(R.id.lvUsers) ListView listView; 

public MainActivityFragment() { 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.fragment_main, container, false); 
    ButterKnife.bind(this, view); 

    ArrayList<User> arrayOfUsers = new ArrayList<User>(); 
    arrayOfUsers.add(new User("Person 1", "Hometown 1")); 
    arrayOfUsers.add(new User("Person 2", "Hometown 2")); 
    arrayOfUsers.add(new User("Person 3", "Hometown 3")); 
    arrayOfUsers.add(new User("Person 4", "Hometown 4")); 
    arrayOfUsers.add(new User("Person 5", "Hometown 5")); 
    // Create the adapter to convert the array to views 
    CustomUsersAdapter adapter = new CustomUsersAdapter(getContext(), arrayOfUsers); 
    // Attach the adapter to a ListView 
    listView.setAdapter(adapter); 

    return view; 
} 

CustomUsersAdapter.java

public class CustomUsersAdapter extends ArrayAdapter<User> { 
private ArrayList<User> users; 

public CustomUsersAdapter(Context context, ArrayList<User> users) { 
    super(context, 0, users); 
    this.users = users; 
} 

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    // Get the data item for this position 
    User user = getItem(position); 
    // Check if an existing view is being reused, otherwise inflate the view 
    if (convertView == null) { 
     convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_user, parent, false); 
    } 
    // Lookup view for data population 
    TextView tvName = (TextView) convertView.findViewById(R.id.tvName); 
    TextView tvHome = (TextView) convertView.findViewById(R.id.tvHometown); 
    // Populate the data into the template view using the data object 
    tvName.setText(user.name); 
    tvHome.setText(user.hometown); 

    convertView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      createDialog(position); 
     } 
    }); 

    // Return the completed view to render on screen 
    return convertView; 
} 

protected void add(String textInput) { 
    add(new User(textInput, "Incomplete")); 
} 

private void createDialog(final int position) { 
    // create an AlertDialog that'll come up when text is clicked 
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(
      getContext()); 

    // set title 
    alertDialog.setTitle("Edit item"); 

    final EditText input = new EditText(getContext()); //uses the EditText from dialog_set 
    input.setInputType(InputType.TYPE_CLASS_TEXT); //makes the dialog ask for plain text input 
    alertDialog.setView(input); 

    // set up buttons 

    alertDialog.setPositiveButton("Save", new DialogInterface.OnClickListener() { 

     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      String textInput = input.getText().toString(); //saves user text as a string 
      users.get(position).name = textInput; 
      notifyDataSetChanged(); 
     } 
    }); 

    alertDialog.setNeutralButton("Complete", new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      users.get(position).hometown = "Complete"; 
      notifyDataSetChanged(); 
     } 
    }); 

    alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      dialog.cancel(); 
     } 
    }); 

    // show it 
    alertDialog.show(); 
} 

układ ListView (z fragment_main.xml)

<ListView 
    android:id="@+id/lvUsers" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentRight="true" 
    android:layout_alignParentTop="true" > 

</ListView> 
+0

'Mogę edytować elementy w ArrayAdapter klikając je". Niemożliwy. Adapter tablicowy nie jest elementem GUI, nie ma widoku, więc można go skasować. Proszę ponownie sformułować. – greenapps

+0

Czy istnieje powód, dla którego masz funkcjonalność FAB w działaniu w stosunku do fragmentu? – BlackHatSamurai

+0

@greenapps, zmieniłem nieco sformułowanie - czy teraz jest jaśniejsze? – songbird813

Odpowiedz

0

Istnieje kilka problemów, które masz. Po pierwsze, próbujesz zaktualizować adapter za pomocą wywołania statycznego, ale nie możesz tego zrobić. Musisz również dostosować metodę add. Powinno to wyglądać następująco:

protected void add(String textInput) { 
    this.users.add(new User(textInput, "Incomplete")); 
} 

To tylko część problemu. Musisz przekazać odwołanie do obiektu do onClickListener. Próbujesz wykonać połączenie statyczne. To nie zadziała. Mogę pomyśleć o umieszczeniu przycisku Floating Action. Jeśli tak, wtedy można łatwo przekazać odwołanie do adaptera:

public class MainActivityFragment extends Fragment { 

private final CustomUsersAdapter adapter; 
@BindView(R.id.lvUsers) ListView listView; 


public MainActivityFragment() { 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.fragment_main, container, false); 
    ButterKnife.bind(this, view); 

    ArrayList<User> arrayOfUsers = new ArrayList<User>(); 
    arrayOfUsers.add(new User("Person 1", "Hometown 1")); 
    arrayOfUsers.add(new User("Person 2", "Hometown 2")); 
    arrayOfUsers.add(new User("Person 3", "Hometown 3")); 
    arrayOfUsers.add(new User("Person 4", "Hometown 4")); 
    arrayOfUsers.add(new User("Person 5", "Hometown 5")); 
    // Create the adapter to convert the array to views 
    adapter = new CustomUsersAdapter(getContext(), arrayOfUsers); 
    // Attach the adapter to a ListView 
    listView.setAdapter(adapter); 

    return view; 
} 

//This creates the Floating Action Button 
    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
    fab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      createDialog(); 
     } 

     private void createDialog() { 
      ArrayList<User> users = new ArrayList<User>(); 

      // create an AlertDialog that'll come up when the add button is clicked 
      AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this); 

      // set title 
      alertDialog.setTitle("Add item"); 

      final EditText input = new EditText(MainActivity.this); //uses the EditText from dialog_set 
      input.setInputType(InputType.TYPE_CLASS_TEXT); //makes the dialog ask for plain text input 
      alertDialog.setView(input); 

      // set up buttons 

      alertDialog.setPositiveButton("Save", new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        String textInput = input.getText().toString(); //saves user text as a string 
        Log.d(TAG, textInput); // records input as a log 
        adapter.add(textInput); 
       } 
      }); 

      alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
       } 
      }); 

      // show it 
      alertDialog.show(); 
     } 
    }); 

Robiąc coś takiego, można przekazać odniesienie do adaptera do wewnętrznej klasy, który został utworzony, a następnie zaktualizować go. Mam nadzieję że to pomoże.