我遇到使用此示例实现的双窗格问题:[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中的细节的方法时(实际上它不加载文本而只加载用户列表),所选项目会改变其背景颜色,但只有几毫秒才会改变其他片段的内容。 我不太确定发生了什么,但我觉得当我更改片段的内容时,活动的整个视图会更新。
所以我的问题是:我对这种行为是否正确以及如何避免这种行为?
感谢您的回复。
答案 0 :(得分:0)
它不优雅,但我这样处理: 事实上,所有内容都来自我在每次屏幕刷新时创建的适配器,因此您必须为Fragments实现回调函数,以便将所选位置传达给父活动,一旦完成,您在分配新选择之前记住所选的最后一项在下一次单击时的位置,以便获得实际位置和最后位置。 回到自定义的ArrayAdapter,在重写的getView方法中,你只需要在构造函数中获取父上下文并从那里获取这些值,最后更改相关项的背景颜色(选中的颜色和最后选择的颜色)到原始背景。
像托尼斯塔克一样会说:我是一个天才。 :P