android - 在onCreateView之前调用的自定义函数

时间:2013-07-22 14:04:29

标签: android android-asynctask

我有一个活动,里面有一个片段,我试图用图片显示网格视图。

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

@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始终为null,这意味着在onCreateView之前调用此函数 - 任何想法为什么会发生这种情况?

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

picsFragment = new PicsFragm(this);

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

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

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

非常感谢

3 个答案:

答案 0 :(得分:1)

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

ul {
margin: 0px;
  padding: 0px;
}

ul li {
  background-color: black;
  border: 1px solid white;
  width: 330px;
  height: 30px;
  line-height: 30px;
  float: left;
  text-align: center;
  list-style: none;
  opacity: .8;
  z-index: 1px;
}

ul li a {
  color: white;
  text-decoration: none;
  display: block;
}

ul li a:hover {
  background-color: ORANGE;
}

ul li ul li {
  display: none;
}

ul li:hover ul li {
  display: block;
  cursor: default;
}

#div1 {
  width: 200px;
  height: 650px;
  background: url(bgi2.jpg);
  text-align: center;
}

#buying_form {
  float: left;
  margin-left: 4px;
  margin-top: 100px;
  width: 326px;
  height: 442px;
  color: MEDIUMBLUE;
  border: 1px solid gray;
  background-color: #708090;
  opacity: .5;
}

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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();
}

我不确定您在execute上调用了哪个帖子AsyncTask,因此我们使用ReentrantLock来确保线程不会相互干扰。