问题:Android问题集锦之控件类

一、EditText:

1、EditText自动换行的问题:

在xml布局中,设置EditText的相关属性:

    android:inputType="textMultiLine"  

亲测此方法可行
备注:(未测试)

其他文章中说可以通过如下方法:

    editText.setSingleLine(false);    //改变默认的单行模式  
    editText.setHorizontallyScrolling(false);  //水平滚动设置为False 

或设置属性:

    android:singleLine="false"  
    android:scrollHorizontally="false" 

二、获取view的可视区域:

    Rect rect = new Rect();
    parentView.getHitRect(rect);
    //子控件是否在可视范围内(至少有一个像素在可视范围内)
    boolean isInRect = childView.getLocalVisibleRect(scrollRect)

三、RecyclerView相关问题

1、ScrollView(RecyclerView[parent] )嵌套RecyclerView[childern]的问题:

原文链接:https://www.cnblogs.com/xgjblog/p/8260061.html
问题说明:进入页面自动跳转到RecyclerView[childern]上,页面会自动滚动

场景描述:如帖子列表中,每个条目会有一个图片列表,帖子列表和图片列表都用的是RecyclerView,当展示帖子列表时,若第一条没有图片的时候,会自动滚动到第二条的照片列表处。

原因猜测:可能是条目中的RecyclerView[childern] 自动获得了焦点才导致滚动的

解决方案:
A、去除条目中Recyclerview的焦点

recyclerview.setFocusableInTouchMode(false);
recyclerview.requestFocus();

B、设置第一个条目(或顶部)某一控件获取焦点
如第一个条目(或顶部)有一个textview,可设置为:

textview.setFocusableInTouchMode(true); 
textview.requestFocus(); 

C、设置根布局的属性

android:descendantFocusability="blocksDescendants"

android:descendantFocusability 有三种值:

  • beforeDescendants:viewgroup会优先其子类控件而获取到焦点
  • afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
  • blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点
    这种方法,会造成页面中Editext焦点被抢导致无法输入,需要用到B方法。

四、嵌套相关问题:

1、解决SwipeRefreshLayout与其嵌套控件的冲突问题

代码:

import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;

import com.xs.lib.core.util.MyLog;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import cn.daoyibigu.R;


/**
 * 解决SwipeRefreshLayout与其嵌套控件的冲突
 * @author hyk
 *
 */
public class MySwipeRefreshLayout extends SwipeRefreshLayout {

    private ListView mListView;
    private OnLoadListener mOnLoadListener;

    // private float firstTouchY;
    // private float lastTouchY;

    private float startY;
    private float startX;
    // 记录viewPager是否拖拽的标记
    private boolean mIsVpDragger;
    private int mTouchSlop;

    private boolean isLoading = false;

    private boolean scrollFlag = false;// 标记是否滑动

    public MySwipeRefreshLayout(Context context) {
        this(context, null);
        init(context);
    }

    public MySwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    // 四种颜色变换
    private void init(Context context) {
        this.setColorSchemeResources(R.color.google_blue, R.color.google_green, R.color.google_red,
                R.color.google_yellow);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

    // set the child view of RefreshLayout,ListView
    public void setChildView(ListView mListView) {
        this.mListView = mListView;
        this.mListView.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView listView, int scrollState) {
                switch (scrollState) {
                    // 当不滚动时
                    case OnScrollListener.SCROLL_STATE_IDLE:// 是当屏幕停止滚动时
                        scrollFlag = false;
                        break;
                    case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:// 滚动时
                        scrollFlag = true;
                        break;
                    case OnScrollListener.SCROLL_STATE_FLING:// 是当用户由于之前划动屏幕并抬起手指,屏幕产生惯性滑动时
                        scrollFlag = true;
                        break;
                }
            }

            @Override
            public void onScroll(AbsListView listView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (null != mOnLoadListener) {
                    if (!isLoading && visibleItemCount > 0 && (firstVisibleItem + visibleItemCount == totalItemCount)) {
                        setLoading(true);
                    }
                }
            }
        });
    }

    public void setLoading(boolean loading) {
        if (mListView == null)
            return;
        isLoading = loading;
        if (loading) {
            if (isRefreshing()) {
                setRefreshing(false);
            }
            mListView.setSelection(mListView.getAdapter().getCount() - 1);
            mOnLoadListener.onLoad(loading);
        }
        // else {
        // firstTouchY = 0;
        // lastTouchY = 0;
        // }
    }

    /**
     * 自动刷新
     */
    public void autoRefresh() {
        try {
            Field mCircleView = SwipeRefreshLayout.class.getDeclaredField("mCircleView");
            mCircleView.setAccessible(true);
            View progress = (View) mCircleView.get(this);
            progress.setVisibility(VISIBLE);

            Method setRefreshing = SwipeRefreshLayout.class.getDeclaredMethod("setRefreshing", boolean.class,
                    boolean.class);
            setRefreshing.setAccessible(true);
            setRefreshing.invoke(this, true, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setOnLoadListener(OnLoadListener loadListener) {
        mOnLoadListener = loadListener;
    }

    public void removeOnLoadListener() {
        mOnLoadListener = null;
    }

    public interface OnLoadListener {
        void onLoad(boolean isStart);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                // 记录手指按下的位置
                startY = ev.getY();
                startX = ev.getX();
                // 初始化标记
                mIsVpDragger = false;
                break;
            case MotionEvent.ACTION_MOVE:
                // 如果viewpager正在拖拽中,那么不拦截它的事件,直接return false;
                if(mIsVpDragger) {
                    return false;
                }

                // 获取当前手指位置
                float endY = ev.getY();
                float endX = ev.getX();
                float distanceX = Math.abs(endX - startX);
                float distanceY = Math.abs(endY - startY);
                // 如果X轴位移大于Y轴位移,那么将事件交给viewPager处理。
                if(distanceX > mTouchSlop && distanceX > distanceY) {
                    mIsVpDragger = true;
                    return false;
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                // 初始化标记
                mIsVpDragger = false;
                break;
        }
        // 如果是Y轴位移大于X轴,事件交给swipeRefreshLayout处理。
        return super.onInterceptTouchEvent(ev);
    }

}

你可能感兴趣的:(问题:Android问题集锦之控件类)