0

我使用此示例实现的双窗格有问题:[http://developer.android.com/reference/android/app/Fragment.html][1]

这是我的片段 1 的代码:

import android.app.FragmentTransaction;
import android.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.Toast;
import ch.gt.ContactCall.R;

public class SideMenuFragment extends ListFragment {

private int currPosition = -1;

private String[] menuItems = new String[]{
        "Contact List",
        "Call Log",
        "Messages",
        "SMS"};


@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("currChoice", currPosition);
}

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

    if(savedInstanceState != null){
        //Restore last state for checked position
        currPosition = savedInstanceState.getInt("currChoice", 0);
    }
}

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

    ActionMenuArrayAdapter adapter = new ActionMenuArrayAdapter(getActivity(), menuItems);
    setListAdapter(adapter);

}

@Override
public View onCreateView(LayoutInflater infl, ViewGroup container, Bundle savedInstanceState) {
    return infl.inflate(R.layout.sidemenu, container, false);

}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    //TODO: récupérer les données de la vue cliquée
    Toast.makeText(
            getActivity(),
            getListView().getItemAtPosition(position).toString() + " position" + position,
            Toast.LENGTH_LONG).show();

    showItemDetails(position);
}

private void showItemDetails(final int index) {
    currPosition = index;

    //getListView().setItemChecked(index, true);
    DetailsFragment details = (DetailsFragment) getFragmentManager().findFragmentById(R.id.fragment2);

    if (details == null || details.getShownIndex() != index) {
        details = DetailsFragment.newInstance(index);

        // Execute a transaction, replacing any existing fragment
        // with this one inside the frame.
        FragmentTransaction ft = getFragmentManager().beginTransaction();

        ft.replace(R.id.fragment2, details);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.commit();

    }


}
}

我的片段 2 代码:

import android.app.ListFragment;
import android.media.AudioFormat;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import ch.gt.ContactCall.R;
import ch.gt.network.*;

import java.net.SocketException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class DetailsFragment extends ListFragment {

    public int mIndex = -1;
    private UdpStreamManager gcUdpm;
    private TcpStreamManager gcTcpm;
//private boolean networkAvailable = false;

public static DetailsFragment newInstance(int index){
    DetailsFragment f = new DetailsFragment();
    f.mIndex = index;
    f.gcUdpm = new UdpStreamManager(8000, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
            1024);
    return f;
}

public int getShownIndex(){
    //return getArguments().getInt("index",0);
    return mIndex;
}

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

    ArrayList<HashMap<String, String>> listitem = new ArrayList<HashMap<String,String>>();

    //HashMap<String, String> map;

    switch (mIndex){
        //User clicked on Contact List
        case 0:
            setContactList(listitem);
            break;
        //User clicked on Call Log
        case 1:
            setCallLogs(listitem);
            break;
        //User clicked on Messages
        case 2:
            break;
        //User clicked on SMS
        case 3:
            break;
        default:
            setWelcomeDisplay();
            break;
    }

}

//Fills XML with contact list
private void setContactList(ArrayList<HashMap<String, String>> listitem) {

    HashMap<String, String> map;
    map = new HashMap<String, String>();
    map.put("name", "toto1");
    map.put("gcpaddress", "101");
    map.put("list_image", String.valueOf(R.drawable.gc_launcher));
    listitem.add(map);

    map = new HashMap<String, String>();
    map.put("name", "toto2");
    map.put("gcpaddress", "102");
    map.put("list_image", String.valueOf(R.drawable.gc_launcher));
    listitem.add(map);

    map = new HashMap<String, String>();
    map.put("name", "mir");
    map.put("gcpaddress", "103");
    map.put("list_image", String.valueOf(R.drawable.gc_launcher));
    listitem.add(map);

    map = new HashMap<String, String>();
    map.put("name", "CANCEL");
    map.put("gcpaddress", "");
    map.put("list_image", String.valueOf(R.drawable.gc_launcher));
    listitem.add(map);

    //SimpleAdapter pout mettre les items de listitem dans le xml contacts_display
    SimpleAdapter adaptItem = new SimpleAdapter(getActivity(), listitem, R.layout.row_layout_contactslist,
            new String[]{"img", "name", "gcpaddress"}, new int[]{R.id.list_image, R.id.name, R.id.gcpaddress});
    setListAdapter(adaptItem);

}

//Fills XML with last calls
private void setCallLogs(ArrayList<HashMap<String, String>> listitem) {

    HashMap<String, String> map;
    map = new HashMap<String, String>();
    map.put("name", "taratata");
    map.put("gcpaddress", "103");
    map.put("list_image", String.valueOf(R.drawable.gc_launcher));
    listitem.add(map);

    map = new HashMap<String, String>();
    map.put("name", "sangoku");
    map.put("gcpaddress", "106");
    map.put("list_image", String.valueOf(R.drawable.gc_launcher));
    listitem.add(map);

    map = new HashMap<String, String>();
    map.put("name", "vegeta");
    map.put("gcpaddress", "107");
    map.put("list_image", String.valueOf(R.drawable.gc_launcher));
    listitem.add(map);

    map = new HashMap<String, String>();
    map.put("name", "CANCEL");
    map.put("gcpaddress", "");
    map.put("list_image", String.valueOf(R.drawable.gc_launcher));
    listitem.add(map);

    //SimpleAdapter pout mettre les items de listitem dans le xml contacts_display
    SimpleAdapter adaptItem = new SimpleAdapter(getActivity(), listitem, R.layout.row_layout_contactslist,
            new String[]{"img", "name", "gcpaddress"}, new int[]{R.id.list_image, R.id.name, R.id.gcpaddress});
    setListAdapter(adaptItem);


}

private void setWelcomeDisplay(){

    String[] items = new String[]{""};
    WelcomeArrayAdapter welcomeAdapter = new WelcomeArrayAdapter(getActivity(), items);
    setListAdapter(welcomeAdapter);
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    //Retrieve username and user address from listview
    Map<String, String> selection = (Map<String, String>) l.getItemAtPosition(position);
    String name = selection.get("name");

    if (name.equals("CANCEL")){
        gcUdpm.disable();
        return;
    }

    String gcpaddress = selection.get("gcpaddress");


    switch (mIndex){
        //User clicked on Contact List
        case 0:
            call();
            Toast.makeText(
                    getActivity(),
                    "name: "+name+" address: "+gcpaddress + " position: " + position,
                    Toast.LENGTH_LONG).show();
            break;
        //User clicked on Call Log
        case 1:

            break;
        //User clicked on Messages
        case 2:
            break;
        //User clicked on SMS
        case 3:
            break;
        default:
            break;
    }
}

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

    return inflater.inflate(R.layout.display, container, false);
}

 //Just a call test function
private void call(){
    try {
        gcUdpm.enable();
        Log.d("VR", "GcUsm enabled and socket created");
    } catch (SocketException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    gcUdpm.startReceive();
    gcUdpm.startStreaming();
}

}

还有我用于悬停处理的 xml:

<?xml version="1.0" encoding="utf-8"?>
<!--Handles color change on button selection-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_window_focused="false" android:state_selected="true" android:drawable="@android:color/transparent" />
    <item android:state_selected="true" android:drawable="@android:color/transparent" />
    <item android:state_pressed="true" android:state_selected="false" android:drawable="@android:color/transparent" />
    <item android:state_selected="false" android:drawable="@color/selected" />
</selector>

在列表视图的每个项目中使用。

我正在实现的双窗格是不同的,因为我没有加载文本,而是通过另一个使用 SimpleAdapter 对象更新其视图的 listfragment 加载另一个列表。当我选择一个项目时,这仅涉及我的第一个 listfragment 的背景颜色,当我不更新 onListItemClick 事件的第二个片段时没关系,当其他项目保持其正常背景为黑色时,所选项目保持灰色。然后,当我调用在另一个 listfragment 中加载详细信息的方法时(实际上它不仅加载文本,还加载用户列表),所选项目更改其背景颜色,但仅在其他片段更改其内容之前几毫秒. 我不太确定发生了什么,但我感觉当我更改片段时,活动的整个视图都会更新'

所以我的问题是:我对这种行为是否正确以及如何避免它?

感谢您的回复。

4

1 回答 1

0

它并不优雅,但我是这样处理的:事实上,一切都来自我在每次屏幕刷新时创建的适配器,所以你必须为你的片段实现回调函数,以便将选定的位置传达给父活动,一旦完成,你在下次单击时分配新选择的位置之前记住最后选择的项目,这样您就可以得到实际位置和最后一个位置。回到您的自定义 ArrayAdapter,在您重写的 getView 方法中,您只需在构造函数中获取父上下文并从那里获取此值,最后更改相关项目的背景颜色(选择为新颜色和最后选择到原始背景。

就像托尼·斯塔克会说的:我是个天才。:P

于 2013-06-13T12:39:17.973 回答