想要在界面上显示一个三级的listview,点击第一级listview时弹出第二级listview,点击第二级listview时弹出第三级listview.,点击第三极listview时弹出Toast,点击后退键或者向右滑动第二级、第三极listview时隐藏。效果如下图:
实现思路:一个Activity,两个fragment,SecondFragment,ThirdFragment;
代码实现:
MainActivity:
放置第一级listview,
1.重新写onKeyDown方法,实现点击回退键使fragment消失。判断fragment回退栈中是否有fragment,若没有点击返回时退出;若有,判断当前fragment是显示还是隐藏,若显示则调用fragment.hide()使其隐藏。
2.在MainActivity中写一个接口MyOnTouchListener,要完成滑动事件,在SecondFragment、ThirdFragment中实现接口。
package com.example.administrator.multilistview;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import fragment.SecondFragment;
public class MainActivity extends AppCompatActivity {
private ListView firstList;
private ArrayList<String> firstData = new ArrayList<String>() {{
add("a");
add("b");
add("c");
add("d");
add("e");
add("f");
add("g");
add("h");
add("i");
add("j");
add("k");
add("l");
add("m");
add("n");
add("o");
add("p");
add("q");
add("r");
add("s");
add("t");
add("u");
add("v");
add("w");
}};
private FragmentManager fm;
private SecondFragment secondFragment;
private ArrayList<MyOnTouchListener> onTouchListeners = new ArrayList<MyOnTouchListener>(10);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
fm = getFragmentManager();
firstList = (ListView) findViewById(R.id.first_list);
firstList.setAdapter(new ArrayAdapter<String>(this, R.layout.first_item, firstData));
firstList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (secondFragment == null) {
instanceFragment();
} else if (fm.findFragmentByTag("second").isHidden()) {
showFragment();
}
}
});
}
//实例化SecondFragment
private void instanceFragment() {
secondFragment = new SecondFragment();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fragment_slide_in_from_right, R.anim.fragment_slide_out_from_left);
fragmentTransaction.add(R.id.second_view, secondFragment, "second");
fragmentTransaction.addToBackStack("second");
fragmentTransaction.commit();
}
//显示ThirdFragment
private void showFragment() {
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fragment_slide_in_from_right, R.anim.fragment_slide_out_from_left);
fragmentTransaction.show(secondFragment);
fragmentTransaction.commit();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//最好不用后退栈中Fragment个数判断消失哪个fragment,
// if (fm.getBackStackEntryCount() == 0) {
// finish();
// return true;
// } else {
// if (fm.getBackStackEntryCount() == 1) {
//
// } else if (fm.getBackStackEntryCount() == 2) {
// }
int a = fm.getBackStackEntryCount();
if (a != 0) {
if (fm.findFragmentByTag("third") != null && !fm.findFragmentByTag("third").isHidden()) {
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fragment_slide_in_from_right, R.anim.fragment_slide_out_from_left);
fragmentTransaction.hide(fm.findFragmentByTag("third"));
fragmentTransaction.commit();
return true;
} else if (fm.findFragmentByTag("second") != null && !fm.findFragmentByTag("second").isHidden()) {
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fragment_slide_in_from_right, R.anim.fragment_slide_out_from_left);
fragmentTransaction.hide(fm.findFragmentByTag("second"));
fragmentTransaction.commit();
return true;
}
} else {
finish();
fm.popBackStack("second", 1);
return true;
}
}
//继续执行父类的其他事件
return super.onKeyDown(keyCode, event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
for (MyOnTouchListener listener : onTouchListeners) {
listener.onTouch(ev);
}
return super.dispatchTouchEvent(ev);
}
public void registerMyOnTouchListener(MyOnTouchListener myOnTouchListener) {
onTouchListeners.add(myOnTouchListener);
}
public void unregisterMyOnTouchListener(MyOnTouchListener myOnTouchListener) {
onTouchListeners.remove(myOnTouchListener);
}
public interface MyOnTouchListener {
public boolean onTouch(MotionEvent ev);
}
}
activity_main.xml:
主要放置一个listview和一个Linear布局,动态加载Fragment。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
tools:context=".MainActivity">
<ListView
android:id="@+id/first_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"></ListView>
<LinearLayout
android:id="@+id/second_view"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical"
android:layout_alignParentRight="true">
</LinearLayout>
</RelativeLayout>
SecondFragment::
1.GestureDetector手势识别
package fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.app.Fragment;
import android.util.Log;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.example.administrator.multilistview.MainActivity;
import com.example.administrator.multilistview.R;
import java.util.ArrayList;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* to handle interaction events.
* create an instance of this fragment.
*/
public class SecondFragment extends Fragment implements GestureDetector.OnGestureListener {
private ArrayList<String> secondData = new ArrayList<String>() {{
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
add("str02");
}};
private ListView secondList;
private GestureDetector mGestureDetector;
private FragmentManager fm;
private ThirdFragment thirdFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_second, container, false);
fm = getFragmentManager();
thirdFragment = new ThirdFragment();
secondList = (ListView) view.findViewById(R.id.second_list);
secondList.setAdapter(new ArrayAdapter<String>(getActivity(), R.layout.first_item, secondData));
secondList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (fm.findFragmentByTag("third") == null) {
instanceFragment();
} else if (fm.findFragmentByTag("third").isHidden()) {
showFragment();
}
}
});
mGestureDetector = new GestureDetector(
getActivity(), this);
MainActivity.MyOnTouchListener myOnTouchListener = new MainActivity.MyOnTouchListener() {
@Override
public boolean onTouch(MotionEvent ev) {
boolean result = mGestureDetector.onTouchEvent(ev);
return result;
}
};
((MainActivity) getActivity())
.registerMyOnTouchListener(myOnTouchListener);
return view;
}
/**
* 实例化ThirdFragment
*/
private void instanceFragment() {
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fragment_slide_in_from_right, R.anim.fragment_slide_out_from_left);
fragmentTransaction.add(R.id.third_view, thirdFragment, "third");
fragmentTransaction.addToBackStack("third");
fragmentTransaction.commit();
}
/**
* 显示ThirdFragment
*/
private void showFragment() {
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fragment_slide_in_from_right, R.anim.fragment_slide_out_from_left);
fragmentTransaction.show(thirdFragment);
fragmentTransaction.commit();
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
/**
* 左右滑动操作
*
* @param e1
* @param e2
* @param velocityX 在X轴滑动的像素
* @param velocityY
* @return
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
//Math.abs取绝对值
if (e2.getX() - e1.getX() > 100 && Math.abs(velocityX) > 40) {
if (fm.getBackStackEntryCount() == 1 || fm.findFragmentByTag("third").isHidden()) {
flingRight();
return true;
}
}
} catch (Exception e) {
}
return false;
}
/**
* //右滑动隐藏当前Fragment
*/
public void flingRight() {
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fragment_slide_in_from_right, R.anim.fragment_slide_out_from_left);
fragmentTransaction.hide(fm.findFragmentByTag("second"));
fragmentTransaction.commit();
}
}
frag_second:
放置第二级listview的fragment,注意最外层必须是RelativeLayout,否则android;layout_alignParentRight="true"不起作用。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="250dp"
android:layout_height="match_parent"
android:background="@color/firstListeSlected"
tools:context="fragment.SecondFragment">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="@+id/second_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"></ListView>
<LinearLayout
android:id="@+id/third_view"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:orientation="vertical">
</LinearLayout>
</RelativeLayout>
</FrameLayout>
ThirdFragment:
放置第三级listview,
package fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.app.Fragment;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.example.administrator.multilistview.MainActivity;
import com.example.administrator.multilistview.R;
import java.util.ArrayList;
public class ThirdFragment extends Fragment implements GestureDetector.OnGestureListener{
private ArrayList<String> thirdData = new ArrayList<String>() {{
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
add("str03");
}};
private ListView thirdList;
private GestureDetector mDetector;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_third, container, false);
thirdList = (ListView) view.findViewById(R.id.third_list);
thirdList.setAdapter(new ArrayAdapter<String>(getActivity(), R.layout.first_item, thirdData));
thirdList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
mDetector = new GestureDetector(
getActivity(), this);
MainActivity.MyOnTouchListener myOnTouchListener = new MainActivity.MyOnTouchListener() {
@Override
public boolean onTouch(MotionEvent ev) {
boolean result = mDetector.onTouchEvent(ev);
return result;
}
};
((MainActivity) getActivity())
.registerMyOnTouchListener(myOnTouchListener);
return view;
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
if (e2.getX() - e1.getX() > 100 && Math.abs(velocityX) > 40) {
flingRight();
return true;
}
} catch (Exception e) {
}
return false;
}
public void flingRight() {//右滑动隐藏当前Fragment
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fragment_slide_in_from_right, R.anim.fragment_slide_out_from_left);
fragmentTransaction.hide(fm.findFragmentByTag("third"));
fragmentTransaction.commit();
}
}
开发总结:
1.开始时想用Activity+popuowindow+popuowindow实现,但是pop(popuowindow简称)在最上边的pop获取焦点,其他listview不能获取焦点,就不能滑动,放弃。
2.Activity+drawer+drawer同理不能实现。
3.自定义接口实现监听 http://blog.csdn.net/subaohao/article/details/22648797
4.inflate方法详解 Android编程之LayoutInflater的inflate方法实例
5.项目运行时出现异常
关于异常“The specified child already has a parent. Youmust call removeView"的解决(举例说明,附源码)
6.源码链接:http://download.csdn.net/detail/hyp1006346386/9396275
存在问题:
1.虽然实现了GectureDetector接口,但是当滑动界面时两个listview同时获取监听事件,当获取监听事件后空操作来解决问题。
欢迎批评指正,交流学习!