2015-06-04 2 views
1

Я ищу способ отображения некоторых данных, которые извлекаются с помощью загрузчика из SQLite DB в AlertDialog. Щелчок по имени в ListView переносит идентификатор записи БД на DialogFragment, и на основании этого должны быть загружены дополнительные данные. Загрузка как таковая работает, но, похоже, она появляется после отображения AlertDialog, потому что в окне сообщения отображается только Null как значение. Кто-нибудь знает, возможно ли вообще передавать данные в AlertDialog? Спасибо за вашу помощь!Использование Loader для отображения данных в AlertDialog?

import java.text.SimpleDateFormat; 
import java.util.Calendar; 
import java.util.Date; 

import android.annotation.SuppressLint; 
import android.app.AlertDialog; 
import android.app.Dialog; 
import android.content.ContentUris; 
import android.content.DialogInterface; 
import android.database.Cursor; 
import android.os.Bundle; 
import android.os.Handler; 
import android.support.v4.app.DialogFragment; 
import android.support.v4.app.LoaderManager.LoaderCallbacks; 
import android.support.v4.content.CursorLoader; 
import android.support.v4.content.Loader; 


@SuppressLint("SimpleDateFormat") 
public class BirthdayDetailsMessage extends DialogFragment implements 
LoaderCallbacks<Cursor> { 

    static String DATE_FORMAT; 
    static final String CALENDAR = "calendar"; 

    private long mRowId; 
    private String mName; 
    private String mDate; 
    private boolean mYearKnown; 
    private String mAge; 
    private Calendar mCalendar; 


    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     mCalendar = Calendar.getInstance();   

     DATE_FORMAT = PrefDateFormat.getPrefDateFormat(getActivity()); 

     Bundle arguments = getArguments(); 

     mRowId = arguments.getLong(ReminderProvider.COLUMN_ROWID); 

     getLoaderManager().initLoader(0, null, this); 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState){ 

     AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 

     builder.setMessage("Birthday: "+ mDate +"\n\n"+"Age: "+ mAge) 
     .setTitle(mName) 
     .setCancelable(false) 
     .setPositiveButton("OK", 
       new DialogInterface.OnClickListener() { 

        @Override 
        public void onClick(DialogInterface dialog, int which) { 
              dialog.cancel();  
        }    
       }); 

     return builder.create(); 
    } 

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     return new CursorLoader(getActivity(), ContentUris.withAppendedId(
       ReminderProvider.CONTENT_URI, mRowId), null, null, null, null); 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor reminder) { 

     if (reminder.getCount() == 0) { 
      new Handler().post(new Runnable() { 
       @Override 
       public void run() { 
        ((OnFinishEditor) getActivity()).finishEditor(); 
       } 
      }); 
      return; 
     } 

     mName = reminder.getString(reminder 
       .getColumnIndexOrThrow(ReminderProvider.COLUMN_NAME)); 

     mYearKnown = (reminder.getInt(reminder 
       .getColumnIndexOrThrow(ReminderProvider.COLUMN_YEAR))==0? false:true); 

     Long dateInMillis = reminder.getLong(reminder 
       .getColumnIndexOrThrow(ReminderProvider.COLUMN_DATE)); 
     Date date = new Date(dateInMillis); 
     mCalendar.setTime(date); 

     SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); 
     mDate = dateFormat.format(mCalendar.getTime()); 

     if (mYearKnown == true){ 
      mAge = String.valueOf(GetDiffYears.getDiffYears(mCalendar)); 
     }else{ 
      mAge = "age not known"; 
     }   

    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> arg0) { 
     // nothing to reset for this fragment 
    } 

} 

EDIT:

Я удалил метод onCreateDialog и использовал следующий вид вместо

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.dialog_fragment, container, 
      false); 
    getDialog().setTitle("Name"); 

    Date = (TextView) v.findViewById(R.id.date); 
    Age = (TextView) v.findViewById(R.id.age); 


    getLoaderManager().initLoader(0, null, this); 

    return v; 
} 

private void updateValues() { 
    getDialog().setTitle(mName); 
    Date.setText("Geburtstag: "+ mDate); 
    Age.setText("Alter: " + mAge);  
} 

В включенных updateValues ​​() в onLoadFinished, и создал XML макет для тела сообщения .. таким образом, он работает нормально.

+1

Я не уверен на 100%, насколько это возможно, чтобы сделать эту работу. Поскольку данные загружаются в фоновый поток, пользовательский интерфейс продолжает настраивать диалог, используя нулевые значения, поскольку фоновый поток еще не закончен. Если вы заморозили поток пользовательского интерфейса, чтобы ждать фоновый поток, значения не будут равны нулю, но вы никогда не захотите блокировать поток пользовательского интерфейса. Мое предложение состоит в том, чтобы создать AsyncTask при щелчке элемента списка и загрузить туда данные, а затем в методе onPostExecute создать диалог. –

+0

ваш ответ в вашем вопросе. Вы делаете диалог перед загрузкой. Используйте Async, как было предложено Джозефом Роке. –

+0

Спасибо, ребята, за быструю помощь ... Я уверен, что это правильный способ запустить начальный код, так как я никогда не работал с Async, и я посмотрел на него, и я боюсь, мне понадобится время, чтобы ознакомиться с ним. Поскольку загрузчик всегда работал правильно, когда я использовал завышенное представление, я пытался работать с помощью настраиваемого DialogFragment, который завышен, см. EDIT .... он работает. – Sauerkraut

ответ

0

Что бы вы хотели сделать, это использовать метод обратного вызова из вашего Loader, чтобы создать диалог. Я бы не поставил Loader в классе диалога, но либо в вызывающем, либо в отдельном классе. Затем вызовите/создайте диалог в onLoadFinished. Реализация будет аналогичной с AsyncTask.

В качестве альтернативы вы можете создать диалог с некоторым текстом по умолчанию и сохранить ссылку на него в своем вызывающем классе. Затем в вашем onLoadFinished обновите значения диалогового окна. Я уверен, что сработает, но я не проверял.