這裏主要是以項目爲例:(代碼註釋寫的很清楚):GoodsFragment.java
public class GoodsFragment extends BaseFragment implements AdapterView.OnItemClickListener, AbsListView.OnScrollListener {
@InjectView(R.id.slh)
StickyListHeadersListView mSlh;
@InjectView(R.id.lv)
ListView mLv;
private MyGroupAdapter groupAdapter;
private MyHeadAdapter headAdapter;
//普通條目的測試數據
private List<Data> dataList = new ArrayList<>();
class Data {
String info;
int headId; //進行分組操作,同組數據該字段相同
int headIndex; //當前條目對應的頭數據所在集合的index下標
}
//頭的測試數據
private List<Head> headList = new ArrayList<>();
class Head {
String info;
int groupFirstIndex; //點擊(左邊的)某個頭時,需要知道其分組容器中對應組元素中第一條數據的下標
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_goods, null);
ButterKnife.inject(this, view);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//獲取測試數據
testData();
headAdapter = new MyHeadAdapter();
mLv.setAdapter(headAdapter);
groupAdapter = new MyGroupAdapter();
mSlh.setAdapter(groupAdapter);
mLv.setOnItemClickListener(this); //左邊條目的點擊事件
mSlh.setOnScrollListener(this); //右邊滑動的監聽
}
private boolean isScroll = false;
/**
* 右邊滾動的事件
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//用戶在滾動右邊
isScroll = true;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
//左邊點擊 導致右邊滾動 只觸發這個方法
if (isScroll) {
Data data = dataList.get(firstVisibleItem);
//當前正在置頂顯示的頭
headAdapter.setSelectedPosition(data.headIndex);
//滾動左邊時 右邊的顯示問題
int firstVisiblePosition = mLv.getFirstVisiblePosition();
int lastVisiblePosition = mLv.getLastVisiblePosition();
if (data.headIndex <= firstVisiblePosition || data.headIndex>=lastVisiblePosition){
mLv.setSelection(data.headIndex);
}
}
}
/**
* 左邊條目的點擊事件
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.i("GoodsFragemnt","左邊條目被點擊了");
headAdapter.setSelectedPosition(position);
Head head = headList.get(position);
mSlh.setSelection(head.groupFirstIndex);
isScroll = false;
}
//獲取測試數據集合
private void testData() {
//頭條目的數據
for (int i = 0; i < 10; i++) {
Head head = new Head();
head.info = "頭數據:" + i;
headList.add(head);
}
//獲取右邊的數據
for (int j = 0; j < headList.size(); j++) {
Head head = headList.get(j);
for (int i = 0; i < 10; i++) {
Data data = new Data();
data.headId = j; //任意值
data.headIndex = j;
data.info = "普通條目數據:第" + j + "組,條目數:" + i;
if (i == 0) { //對應組元素中第一條數據的下標
head.groupFirstIndex = dataList.size();
}
dataList.add(data);
}
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.reset(this);
}
/**
* 右邊條目的adapter
*/
private class MyGroupAdapter extends BaseAdapter implements StickyListHeadersAdapter {
//分組
@Override
public View getHeaderView(int position, View convertView, ViewGroup parent) {
Data data = dataList.get(position);
//頭所在集合下標
Head head = headList.get(data.headIndex);
TextView tv = new TextView(MyApplication.getContext());
tv.setText(head.info);
tv.setBackgroundColor(Color.GRAY);
return tv;
}
@Override
public long getHeaderId(int position) {
//position是普通條目的 裏面有HeadId
int headId = dataList.get(position).headId;
return headId;
}
//普通條目
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = new TextView(MyApplication.getContext());
tv.setText(dataList.get(position).info);
tv.setTextColor(Color.GRAY);
return tv;
}
}
/**
* 左邊條目的adapter
*/
private class MyHeadAdapter extends BaseAdapter {
private int mSelectedPosition;
@Override
public int getCount() {
return headList.size();
}
@Override
public Object getItem(int position) {
return headList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = new TextView(MyApplication.getContext());
tv.setText(headList.get(position).info);
tv.setLayoutParams(new ListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 80));
tv.setGravity(Gravity.CENTER);
tv.setTextSize(16);
tv.setTextColor(Color.BLACK);
if (position == mSelectedPosition) {
tv.setBackgroundColor(Color.WHITE);
} else {
tv.setBackgroundColor(Color.GRAY);
}
return tv;
}
/**
* 左邊條目的選擇
**/
public void setSelectedPosition(int selectedPosition) {
if (mSelectedPosition == selectedPosition){
return; //不用刷新
}
mSelectedPosition = selectedPosition;
notifyDataSetChanged();
}
}
}
佈局文件:fragment_goods.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<ListView
android:id="@+id/lv"
android:layout_width="100dp"
android:layout_height="match_parent"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:scrollbars="none"
>
</ListView>
<se.emilsjolander.stickylistheaders.StickyListHeadersListView
android:id="@+id/slh"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent">
</se.emilsjolander.stickylistheaders.StickyListHeadersListView>
</LinearLayout>
例外使用stickylistheaders之前需要導入依賴
//詳情聯動列表stickylistheaders
compile 'se.emilsjolander:stickylistheaders:2.7.0'
具體的stickylistheaders使用可自行百度