Android: перерисуйте GridView после добавления дочернего элемента

Я пытаюсь создать представление сетки, которое дает пользователю возможность создать нового дочернего элемента, щелкнув последний элемент в представлении сетки. У меня проблема с перерисовкой вида. На самом деле после того, как пользователь создаст новый дочерний элемент через диалоговое окно предупреждения, мне нужно обновить представление сетки, чтобы сделать этот дочерний элемент видимым. Я долго искал решение, и все, что я нашел, это:

adapter.notifyDataSetChanged();
gridView.invalidateViews();
gridView.setAdapter(adapter);

Который является частью моего кода, но, по крайней мере, по-видимому, ничего не делает. Приведенный ниже код — это всего лишь onCreateView() из класса PlaceholderFragment в шаблоне Android для действия с пролистыванием вкладок. Разработка приложения здесь все еще находится в начале, но я уже застрял в этой проблеме.

public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        final View rootView = inflater.inflate(R.layout.fragment_one, container, false);
        final GridView gridView = (GridView) rootView.findViewById(R.id.gridview);
        final GridAdapter adapter =new GridAdapter(getActivity());
        gridView.setAdapter(adapter);
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v,
                                    int position, long id) {
                if(position==0){
                    LayoutInflater inflater = getActivity().getLayoutInflater();
                    View newidea= inflater.inflate(R.layout.newidea, null);
                    final TextView txtname = ((TextView) newidea.findViewById(R.id.name));
                    final TextView txtdesc = ((TextView) newidea.findViewById(R.id.desc));
                    final Spinner spinner=((Spinner)newidea.findViewById(R.id.spinner));
                    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                    builder.setIcon(R.drawable.type_add)
                            .setPositiveButton("Create", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int id) {
                                    String name = txtname.getText().toString();
                                    String desc = txtdesc.getText().toString();
                                    DataReceiver dr = new DataReceiver(getActivity().getBaseContext(), name, desc,Integer.toString(spinner.getSelectedItemPosition()));
                                    dr.writeFile();
                                    dialog.dismiss();
                                    adapter.notifyDataSetChanged();
                                    gridView.invalidateViews();
                                    gridView.setAdapter(adapter);
                                }
                            }).setNegativeButton("Forgot the idea?", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            dialog.dismiss();
                        }
                    }).setView(newidea)
                            .setTitle("New Idea");
                    AlertDialog dialog = builder.create();
                    dialog.show();
                } else {
                    Toast.makeText(
                            getActivity(),
                            ((TextView) v.findViewById(R.id.grid_item_label))
                                    .getText(), Toast.LENGTH_SHORT).show();
                }

            }
        });

        return rootView;
    }

}

ОБНОВЛЕНИЕ после запросов на публикацию кода.

Вот GridAdapter. Все работает нормально, единственное, что мне все еще нужно закрыть и снова открыть приложение, чтобы увидеть, как вид сетки перерисовывается и обновляется.

public class GridAdapter extends BaseAdapter {
private Context context;
boolean filesyet;
File f[];
public GridAdapter(Context context) {
    this.context = context;
    filesyet=filesYet();
}

@Override
public Object getItem(int i) {
    return null;
}

@Override
public long getItemId(int i) {
    return 0;
}

public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View gridView;
    if (convertView == null) {
        gridView = inflater.inflate(R.layout.griditem, null);
        TextView title = (TextView) gridView
                .findViewById(R.id.grid_item_label);
        LinearLayout background = (LinearLayout) gridView
                .findViewById(R.id.grid_item);

        if(position==0){
            title.setText("");
            Drawable d= context.getResources().getDrawable(R.drawable.type_add);
            background.setBackground(d);
        }else {
            title.setText(f[position].getName());
            Drawable d;
            int selected=0;
            try {
                byte[] buffer = new byte[1];
                new FileInputStream(f[position]).read(buffer,0,buffer.length);
                selected=Integer.valueOf(new String(buffer));
            } catch (FileNotFoundException e){
                e.printStackTrace();
            } catch (IOException e){
                e.printStackTrace();
            }
            switch(selected){
                case 1:
                    d=context.getResources().getDrawable(R.drawable.type_app);
                    break;
                case 2:
                    d=context.getResources().getDrawable(R.drawable.type_engi);
                    break;
                case 3:
                    d=context.getResources().getDrawable(R.drawable.type_event);
                    break;
                default:
                    d=context.getResources().getDrawable(R.drawable.eureka);
                    break;
            }
            background.setBackground(d);
        }

    } else {
        gridView = (View) convertView;
    }

    return gridView;
}

@Override
public int getCount() {
    if (filesyet) {
        return f.length;
    } else {
        return 1;
    }
}

Boolean filesYet(){
    try {
        String path = context.getFilesDir().toString();
        this.f = new File(path).listFiles();
        System.out.println(f.toString());
        return true;
    } catch (NullPointerException e){
        System.out.println("NULL");
        return false;
    }
}

Спасибо за помощь


person Francesco Ambrosini    schedule 29.11.2013    source источник
comment
Ваш адаптер знает, что у него есть новый элемент? что делает DataReceiver .writefile()?   -  person Tristan Burnside    schedule 29.11.2013
comment
Разве notifydatasetchanged не сообщает адаптеру, что у него есть новый элемент? Функция writefile() DataReceiver записывает имя и описание файла в приватный каталог приложения. Позже он будет использоваться в качестве базы данных для хранения информации обо всех элементах в представлении сетки (нажатие на них должно открыть новый экран со всей информацией об элементе).   -  person Francesco Ambrosini    schedule 29.11.2013
comment
Да, notifyDataSetChanged сообщает адаптеру, что у него есть новый элемент. Но вопрос, вы добавляете этот новый пункт в данные адаптера? Если вы не добавите его, то при уведомлении он не найдет новый элемент.. Пожалуйста, опубликуйте свой код GridAdapter..   -  person Amulya Khare    schedule 29.11.2013


Ответы (1)


Вы загружаете список файлов только при создании адаптера в конструкторе. Поскольку вы не создаете новый конструктор, метод filesYet() больше не вызывается и список файлов не обновляется.

Чтобы сделать это обновление, вы можете переопределить функцию notifydatasetchanged в адаптере.

@Override
public void notifyDataSetChanged (){
    filesyet = filesYet();
    super.notifyDataSetChanged();
}
person Tristan Burnside    schedule 29.11.2013
comment
Извините, я думал, что сделал! - person Francesco Ambrosini; 29.11.2013