0

我有一个活动,其中有一个片段,我试图在其中显示带有图片的网格视图。

如果我尝试访问片段的 onCreateView() 中的视图,我会得到一个非空处理程序并且一切正常:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.bar_pics_grid, container, false);
    GridView gridview = (GridView) v.findViewById(R.id.gridview);
    return v;

但是,由于我需要先从数据库中获取数据,所以我在自定义函数中访问了 gridview:

public void loadData(Bar bar) {

    if (showBarDetails.getBar() != null) {

        bar = showBarDetails.getBar();
        GridView gridview = (GridView) getView().findViewById(R.id.gridview);
        barImageArray = bar.getImages().toArray(new BarImage[bar.getImages().size()]);
        gridview.setAdapter(new PicsAdapter(showBarDetails, barImageArray));

    }
}

在后一种情况下,gridview 始终为空,这意味着此函数在 onCreateView 之前调用 - 任何想法为什么会发生这种情况?

我在活动的 onCreate 函数中初始化 Fragment,如下所示:

picsFragment = new PicsFragm(this);

然后我有一个 AsyncTask 从我调用的数据库中提取数据:

@Override
protected void onPostExecute(AsyncTaskResult<Bar> result) {

    if (result.getError() == null) {
        sbd.setBar(result.getResult());
        if (sbd.getPicsFragment().isResumed())
            sbd.getPicsFragment().loadData(sbd.getBar());
    } 
}

非常感谢

4

3 回答 3

1

由于您的自定义函数是在 onCreateView 之前调用的,因此我建议在您的自定义函数中初始化一个全局变量,然后在您的 onCreateView 方法中调用该变量。

//global variable declaration like a string or data source e.g
String myValue;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.bar_pics_grid, container, false);
    //Get your global variable here
    String getValue = myValue;
    GridView gridview = (GridView) v.findViewById(R.id.gridview);

    return v;
}


public void loadData(String bar) {

    //initialize your global variable here
    myValue = bar;
}
于 2016-08-12T13:56:02.637 回答
0

我会用 aReentrantLock来解决这个问题。在片段活动中创建一个变量来保存数据库数据:

private ReentrantLock dataLocker = new ReentrantLock();
private PicsAdapter adapter = null;

loadData(Bar bar)与其直接将其加载到网格视图中,不如将其加载到该变量中:

if (showBarDetails.getBar() != null)
{
    bar = showBarDetails.getBar();
    barImageArray = bar.getImages().toArray(new BarImage[bar.getImages().size()]);
    dataLocker.lock();
    try
    {
        adapter = new PicsAdapter(showBarDetails, barImageArray);
        //Check if the grid view is made (this is run after inflation)
        GridView gridview = (GridView) getView().findViewById(R.id.gridview);
        if (gridview != null)
        {
            gridview.setAdapter(adapter);
        }
    }
    finally
    {
        dataLocker.unlock();
    }
}

然后,当您膨胀视图时,您会在膨胀时锁定 dataLocker。充气后,如果适配器已经存在,请设置它。

dataLocker.lock();
try
{
    View v = inflater.inflate(R.layout.bar_pics_grid, container, false);
    GridView gridview = (GridView) v.findViewById(R.id.gridview);
    if (adapter != null)
        gridview.setAdapter(adapter);
    return v;
}
finally
{
    dataLocker.unlock();
}

我不确定您在 on 上调用了哪个线程executeAsyncTask因此我们使用ReentrantLock来确保线程不会相互干扰。

于 2013-07-22T14:24:18.703 回答
0

Android 文档建议从一个 Activity 到一个托管的 Fragment 进行通信,该 Fragment 可以定义一个回调接口并要求宿主 Activity 实现它。基本模式涉及在您的片段中实现 onAttach,并将活动转换为回调接口。

请参阅http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity

于 2013-07-22T14:15:02.790 回答