listview自动滑动到合适的位置,方便用户回复体验的Demo

思路:用反射的方法,调用listview中的方法,使listview自动滑动一定的距离。
难点:得到要滑动的距离
步骤:
1、监听键盘的弹出,在回调方法中,计算应该滑动的距离,
2、发送message给handler。在handler中用反射调用方法,使listview滑动一定的距离

/**
* Created by 张玉水 on 2014/6/20.
*/
public class NotesAndAskFragment extends BaseFragment implements OnActionViewClickListener {

private PullableListView noteAskListView;
private NoteAndAskAdapter noteAndAskAdapter;
private ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener;
private View rootView;
private AutoLinearLayout llView;
private View myView;

//在handler中用反射调用方法,使listview滑动一定的距离
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int rex = (int) msg.obj;
//调用的方法
scrollVertical(noteAskListView, getActivity(), rex + llView.getMeasuredHeight());
ToastUtil.showNormalShortToast(“–total–”+( rex + llView.getMeasuredHeight()));
myView = null;
}
};
private boolean isScroll = false;
private JSONObject mJsonObject;
private AutoLinearLayout all_newnote;
private EditText et_newnote;
private Button btn_newnote;
private String bcType;
private Boolean isAddNewNote=true;
private String objectId;
private String fUserId;
private Boolean isFromHome;

@Override
protected View initView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    rootView = inflater.inflate(R.layout.fragment_noteandask, container, false);

    return rootView;
}
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    **//键盘弹出,将relativelayout悬浮的输入框和回复按钮顶上去的必要方法配置**
    getActivity().getWindow().setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
                    | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

   }

@Override
protected void initData(View view, Bundle savedInstanceState) {


    //setTitleColor(view,R.color.merchanttextcolor);

    noteAskListView = (PullableListView) view.findViewById(R.id.note_ask_listview);
    noteAndAskAdapter = new NoteAndAskAdapter(getContext());
    noteAndAskAdapter.setOnActionViewClickListener(this);
    noteAskListView.setAdapter(noteAndAskAdapter);


    ((View) view.findViewById(R.id.actionbar_back))
            .setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    rootView.getViewTreeObserver()
                            .removeGlobalOnLayoutListener(
                                    onGlobalLayoutListener);
                    onGlobalLayoutListener = null;
                    popBackStack();
                }
            });

    llView = (AutoLinearLayout) view.findViewById(R.id.edittext_btn);



}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.note_num:
             Integer tag = (Integer) v.getTag();
               showInputKeyboard(tag);
                myView = v;
                isScroll = true;

            break;
        case R.id.btn_newnote:
            addNewNote();

            break;

// case R.id.delete:
// Integer tagItemDelete = (Integer) v.getTag();
// showDeleteItemDelog(tagItemDelete);
// break;
case R.id.myNoteAskId:// 10000 点击的是动态添加textview的回复
clickTextReply(v);
break;

    }
}




@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {

            // 比较Activity根布局与当前布局的大小
            int heightDiff = rootView.getRootView().getHeight()
                    - rootView.getHeight();
            if (et_newnote.hasFocus()){
                //当增加新的noteAndAsk的时候。不要显示llview。直接return掉
                return;
            }
            if (heightDiff > 500) {
                // 大小超过100时,一般为显示虚拟键盘事件
                // ToastUtil.showNormalShortToast(rootView.getRootView().getHeight()+"显示键盘"+rootView.getHeight());
                llView.setVisibility(View.VISIBLE);
                llView.findViewById(R.id.et).requestFocus();

                if (isScroll && myView != null) {
                    //在回调事件中,计算应该滑动的距离
                    int offset = getOffset(myView, heightDiff);
                    //ToastUtil.showNormalShortToast("==offset==:"+offset);
                    Message message = new Message();
                    message.obj = offset;
                    //发送消息
                    handler.sendMessage(message);
                    isScroll = false;

                }


                all_newnote.setVisibility(View.GONE);


            } else {
                // 大小小于100时,为不显示虚拟键盘或虚拟键盘隐藏
                // ToastUtil.showNormalShortToast("隐藏键盘");
                llView.setVisibility(View.GONE);


            }
        }
    };
    rootView.getViewTreeObserver().addOnGlobalLayoutListener(
            onGlobalLayoutListener);
}




/**
 * 显示键盘和输入框
 *
 * @param tag
 * @author 张玉水
 * @date 2016-5-16 下午6:41:11 TODO
 */
private void showInputKeyboard(final int... tag) {

    llView.setVisibility(View.VISIBLE);
    final EditText et = (EditText) llView.findViewById(R.id.et);
    et.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            return false;
        }
    });
    et.requestFocus();
    Button btn = (Button) llView.findViewById(R.id.btn_response);

       btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String content = et.getText().toString().trim();
            if (!TextUtils.isEmpty(content)) {
                // 1、将评论内容发送到服务器,2、并在返回成功的回调中更新UI
                sendCommentToService(content, noteAndAskAdapter.getData(), tag);

            }
            llView.setVisibility(View.GONE);

            KeyboardUtil.hideKeyBoard(getActivity());
            et.setText("");
        }
    });
    KeyboardUtil.showKeyBoard(getActivity());


}


//得到条目应该滚动的距离
public int getOffset(View v, int heightDiff) {
    int offset = getLocationBottom(v) - (Config.displayHeight - heightDiff);

    AutoLinearLayout ll_note_ask_content = (AutoLinearLayout) v.getRootView().findViewById(R.id.ll_note_ask_content);

    if (ll_note_ask_content==null){
        ll_note_ask_content= (AutoLinearLayout) ((ArrayList)v.getTag()).get(1);
    }

    ll_note_ask_content.measure(0,0);
    int measuredHeight = ll_note_ask_content.getMeasuredHeight();


    return offset+measuredHeight;
}

// //得到条目底部到 屏幕的距离
public int getLocationBottom(View v) {
int[] loc = new int[4];
int[] location = new int[2];
v.getLocationOnScreen(location);
loc[0] = location[0];
loc[1] = location[1];
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
v.measure(w, h);

    loc[2] = v.getMeasuredWidth();
    loc[3] =  v.getMeasuredHeight()+loc[1];//底部距离 屏幕上边的 高

    //base = computeWH();
    return loc[3];
}
/**
 * scroll Vertical
 *
 * @param y 垂直滑动的距离
 */
public void scrollVertical(final ListView listView, Activity activity, final int y) {
    if (listView == null)
        return;
    activity.runOnUiThread(new Runnable() { //执行自动化测试的时候模拟滑动需要进入UI线程操作
        @Override
        public void run() {
            invokeMethod(listView, "trackMotionScroll", new Object[]{0, -y}, new Class[]{int.class, int.class});
        }
    });
}

/**
 * 遍历当前类以及父类去查找方法,例子,写的比较简单
 *
 * @param object
 * @param methodName
 * @param params
 * @param paramTypes
 * @return
 */
public Object invokeMethod(Object object, String methodName, Object[] params, Class[] paramTypes) {
    Object returnObj = null;
    if (object == null) {
        return null;
    }
    Class cls = object.getClass();
    Method method = null;
    for (; cls != Object.class; cls = cls.getSuperclass()) { //因为取的是父类的默认修饰符的方法,所以需要循环找到该方法
        try {
            method = cls.getDeclaredMethod(methodName, paramTypes);
            break;
        } catch (NoSuchMethodException e) {

// e.printStackTrace();
} catch (SecurityException e) {
// e.printStackTrace();
}
}
if (method != null) {
method.setAccessible(true);
try {
returnObj = method.invoke(object, params);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return returnObj;
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值