2015-08-30 35 views
2

我有一個自定義list view,佈局包含兩個稱爲「上」和「下」的佈局。佈局可見性更改後,微調器值消失+特定流程

上部佈局包含微調器,設置和刪除按鈕。 底部佈局包含text view和後退按鈕。

默認底部佈局是GONE狀態,並且當用戶點擊按鈕set佈局upperGONE和底部是VISIBLE(在底部佈局點擊返回按鈕將返回上底部背面)。

我的問題是微調值是特定流後消失:

流程1:

  1. 添加兩個項目
  2. 點擊設置按鈕上的第一個項目
  3. 刪除第二項目
  4. 點擊第一項上的'返回'按鈕

Spinner value is disappear

流程2:

  1. 單擊設置
  2. 旋轉屏幕
  3. 單擊後退

只是要清楚,微調值存在,如果放下它,你會找到名稱(我有android:configChanges="keyboardHidden|orientation|screenSize"在我的清單中)。

那麼,爲什麼Spinner的價值在這些流動後消失了?

這裏是我的代碼:

Names.java

public class Names 
{ 
    private String name; 
    private int nameIndex; 
    private Boolean isNameOnTop; 


    public Names() 
    { 
     name = ""; 
     isNameOnTop = true; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public int getNameIndex() { 
     return nameIndex; 
    } 

    public void setNameIndex(int nameIndex) { 
     this.nameIndex = nameIndex; 
    } 

    public Boolean getIsNameOnTop() { 
     return isNameOnTop; 
    } 

    public void setIsNameOnTop(Boolean isNameOnTop) { 
     this.isNameOnTop = isNameOnTop; 
    } 
} 

MainActivity.Java

public class MainActivity extends Activity 
{ 
    ArrayList<Names> namesArray = new ArrayList<>(); 
    ListView lvNames; 
    ListviewAdapter adapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     lvNames = (ListView) findViewById(R.id.listView); 
     adapter = new ListviewAdapter(this, namesArray); 
     lvNames.setAdapter(adapter); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     int id = item.getItemId(); 
     if (id == R.id.action_add) 
     { 
      namesArray.add(new Names()); 
      adapter.notifyDataSetChanged(); 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 
} 

ListviewAdapter.java

public class ListviewAdapter extends BaseAdapter 
{ 
    public Activity context; 
    public LayoutInflater inflater; 
    private ArrayList<Names> namesID; 
    private boolean isDeleted; 

    public ArrayList<Names> getNamesID() { 
     return namesID; 
    } 

    public void setNamesID(ArrayList<Names> namesID) { 
     this.namesID = namesID; 
    } 

    // Constructor 
    public ListviewAdapter(Activity context, ArrayList<Names> names) 
    { 
     super(); 
     setNamesID(names); 

     this.context = context; 
     this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    @Override 
    public int getCount() { 
     return getNamesID().size(); 
    } 

    @Override 
    public Names getItem(int position) { 
     return getNamesID().get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return 0; 
    } 
public class ViewHolder 
    { 
     RelativeLayout relativeLayout_Upper; 
     RelativeLayout relativeLayout_Bottom; 

     Spinner spNames; 
     Button btn_set, btn_remove, btn_back; 
     TextView tvChosen; 

     int index; 
    } 

    @Override 
    public View getView(final int i, View view, final ViewGroup viewGroup) { 
     final ViewHolder holder; 
     if (view == null) { 
      holder = new ViewHolder(); 
      view = inflater.inflate(R.layout.listview_row, null); 

      holder.relativeLayout_Upper = (RelativeLayout) view.findViewById(R.id.lvRow_upper_layout); 
      holder.relativeLayout_Bottom = (RelativeLayout) view.findViewById(R.id.lvRow_bottom_layout); 
      holder.spNames = (Spinner) view.findViewById(R.id.spNames); 
      holder.btn_set = (Button) view.findViewById(R.id.btn_set); 
      holder.btn_remove = (Button) view.findViewById(R.id.btn_remove); 
      holder.btn_back = (Button) view.findViewById(R.id.btn_back); 
      holder.tvChosen = (TextView) view.findViewById(R.id.tv_chosen); 
      view.setTag(holder); 
     } 
     else 
      holder = (ViewHolder) view.getTag(); 
     holder.index = i; 

     if (isDeleted) 
     { 
      holder.spNames.setSelection(getItem(holder.index).getNameIndex()); 
      holder.tvChosen.setText("Chosen: " + getItem(holder.index).getName()); 

      if (getItem(holder.index).getIsNameOnTop()) 
      { 
       holder.relativeLayout_Upper.setVisibility(View.VISIBLE); 
       holder.relativeLayout_Bottom.setVisibility(View.GONE); 
      } 
      else 
      { 
       holder.relativeLayout_Upper.setVisibility(View.GONE); 
       holder.relativeLayout_Bottom.setVisibility(View.VISIBLE); 
      } 
     } 

     // pop spinner names 
     String[] names = new String[]{"Tom", "Ben", "Gil", "Adam", "Moshe", "Adi", "Michael", "Yasmin", "Jessica", "Caroline", "Avi", "Yael"}; 
     final ArrayAdapter<String> spNamesAdapter = new ArrayAdapter<String> 
       (view.getContext(), android.R.layout.simple_spinner_dropdown_item, names); 
     spNamesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     holder.spNames.setAdapter(spNamesAdapter); 

     holder.spNames.setSelection(getItem(holder.index).getNameIndex()); 
     holder.spNames.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
      @Override 
      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
       //holder.spNames.setTag(position); 
       getItem(holder.index).setNameIndex(position); 
      } 

      @Override 
      public void onNothingSelected(AdapterView<?> parent) { 

      } 
     }); 

     holder.btn_set.setTag(i); 
     holder.btn_set.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       getItem(holder.index).setName(holder.spNames.getSelectedItem().toString()); 
       int position = (Integer) v.getTag(); 
       holder.tvChosen.setText("Chosen: " + getItem(position).getName()); 
       holder.relativeLayout_Upper.setVisibility(View.GONE); 
       holder.relativeLayout_Bottom.setVisibility(View.VISIBLE); 
       getItem(holder.index).setIsNameOnTop(false); 
      } 
     }); 

     // remove 
     holder.btn_remove.setTag(i); 
     holder.btn_remove.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       int position = (Integer) v.getTag(); 
       namesID.remove(position); 
       notifyDataSetChanged(); 
       isDeleted = true; 
      } 
     }); 

     // back 
     holder.btn_back.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       holder.relativeLayout_Upper.setVisibility(View.VISIBLE); 
       holder.relativeLayout_Bottom.setVisibility(View.GONE); 
       getItem(holder.index).setIsNameOnTop(true); 
      } 
     }); 

     return view; 
    } 
} 

activity_main.xml:只包含ListView

upper_view.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="horizontal" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <Spinner 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/spNames" /> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="SET" 
     android:id="@+id/btn_set" /> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="REMOVE" 
     android:id="@+id/btn_remove" /> 
</LinearLayout> 

bottom_view。XML

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="horizontal" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textAppearance="?android:attr/textAppearanceLarge" 
     android:text="Chosen:" 
     android:id="@+id/tv_chosen" 
     android:layout_marginRight="20dp" /> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="BACK" 
     android:id="@+id/btn_back" /> 
</LinearLayout> 

listview_row.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <RelativeLayout 
     android:orientation="vertical" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/lvRow_upper_layout"> 

     <include 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      layout="@layout/upper_view" 
      android:id="@+id/includeRow_register" 
      android:layout_alignParentLeft="true" 
      android:layout_marginLeft="0dp" 
      android:layout_alignParentTop="true" 
      android:layout_marginTop="0dp" /> 
    </RelativeLayout> 

    <RelativeLayout 
     android:orientation="vertical" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/lvRow_bottom_layout" 
     android:visibility="gone"> 

     <include 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      layout="@layout/bottom_view" 
      android:id="@+id/includeRow_showData" 
      android:layout_alignParentLeft="true" 
      android:layout_marginLeft="0dp" 
      android:layout_alignParentTop="true" 
      android:layout_marginTop="0dp" /> 
    </RelativeLayout> 
</LinearLayout> 
+0

使用隱形而是走了 – meda

+0

@meda,感謝,但'INVISIBLE'的這不是好主意,因爲它保留佈局空間(導致行之間的空白空間) – AsfK

+0

你的意思是說,數據是在那裏的微調所有的時間,如果你點擊它,它會顯示,對嗎? –

回答

1

在你ListviewAdapter,更改:

// back 
    holder.btn_back.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      holder.relativeLayout_Upper.setVisibility(View.VISIBLE); 
      holder.relativeLayout_Bottom.setVisibility(View.GONE); 
      getItem(holder.index).setIsNameOnTop(true); 
     } 
    }); 

到:

// back 
    holder.btn_back.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      holder.relativeLayout_Upper.setVisibility(View.VISIBLE); 
      holder.relativeLayout_Bottom.setVisibility(View.GONE); 
      getItem(holder.index).setIsNameOnTop(true); 
      notifyDataSetChanged(); 
      // OR you can use this 
      // holder.spNames.requestLayout(); 
     } 
    }); 
+0

非常感謝!我必須等待23小時才能獲得賞金......你知道爲什麼要在這裏解釋通知方法嗎? – AsfK

+1

嗯,不會說謊,但你的代碼有點雜亂,所以我沒有閱讀每一行,但我注意到這一行:'holder.spNames.setSelection(getItem(holder.index).getNameIndex());'。所以當我移除第二個項目時,我**猜到了第二個項目的視圖被第一個項目重用,這就是爲什麼你的「微調」失去了選擇。所以我使用'notifyDataSetChanged();'來觸發'getView()'來再次設置正確的選擇。給我一分鐘我會檢查我的**猜測**是否屬實:D – Leo

+1

可悲的是,我的猜測是錯誤的,第一個項目仍然使用它的舊觀點。實際上,我認爲你的代碼沒有問題,但是渲染系統(我再次猜測)是因爲在刪除第二個項目後,按回來,然後點擊Spinner,展開的列表仍然滾動到正確的選定項目的位置,它只是當它摺疊時不會顯示選定的項目(這真的很奇怪!)。所以基本上我們通過'notifyDataSetChanged()'再次調用Spinner的'setSelection'來解決這個奇怪的問題。 – Leo

0

每當你點擊onOptionsItemSelected(方法 「添加」)對象添加新的名稱()進入榜單,並在名稱類,屬性名稱的值設置爲「」 我想這就是爲什麼你得到一個空的項目在微調。

+0

否否否,當用戶添加新項目時重置所有微調器。請在下次檢查自己 – AsfK

+0

我想我沒有得到你的問題... –