如何让edittext在activity起始的时候不自动获得焦点

如何让edittext在activity起始的时候不自动获得焦点,第1张

在进入一个Activity时,如果这个Activity中有EditText,则这个EditText会自动获取焦点,然后就会d出软键盘,这样给用户体验不是很好。所以一般会通过代码控制让EditText不获取焦点。常用的方式如下,在Activity的布局文件中加上如下代码:

<!-- 输入焦点控制 -->

<LinearLayout

android:layout_width="0px"

android:layout_height="0px"

android:focusable="true"

android:focusableInTouchMode="true" />

在日前开发的一个项目中界面中除了EditText就是Spinner 和Button等空间,EditText 获取焦点以后,点击Spinner总是无法移除焦点:采取如下方式解决,

当点击Spinner时让EditText失去焦点即可:(见标红代码)

// 初始化两个LayoutInflater对象

inflater = (LayoutInflater) getSystemService(ContextLAYOUT_INFLATER_SERVICE);

layoutInflater = (LayoutInflater) getSystemService(ContextLAYOUT_INFLATER_SERVICE);

et_name = (EditText) findViewById(Ridet_name);

ib_add = (ImageButton) findViewById(Ridib_add);

ib_clear = (Button) findViewById(Ridib_clear);

ib_query = (Button) findViewById(Ridib_query);

ib_down = (Button) findViewById(Ridib_down);

ib_save = (Button) findViewById(Ridib_save);

ib_back = (ImageButton) findViewById(Ridib_back);

// ib_sex = (ImageButton) findViewById(Ridib_sex) ;

ib_addsetOnClickListener(this);

ib_clearsetOnClickListener(this);

ib_querysetOnClickListener(this);

ib_downsetOnClickListener(this);

ib_savesetOnClickListener(this);

ib_backsetOnClickListener(this);

// ib_sexsetOnClickListener(this) ;

// 性别

ArrayAdapter<String> sexAdapter = new ArrayAdapter<String>(this, androidRlayoutsimple_spinner_item);

sexAdaptersetDropDownViewResource(androidRlayoutsimple_spinner_dropdown_item);

String sexString;

sexAdapterclear();

int position = 0;

for (int i = 0; i < sexListlength; i++) {

sexString = sexList[i];

sexAdapteradd(sexString);

}

sp_sex = (Spinner) findViewById(Ridsp_sex);

sp_sexsetAdapter(sexAdapter);

sp_sexsetFocusable(true);

sp_sexsetSelection(position);

sp_sexsetOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

// TODO Auto-generated method stub

et_nameclearFocus();

return false;

}

});

sp_sexsetOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

// TODO Auto-generated method stub

et_nameclearFocus();

return false;

}

});

sp_monthsetOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

// TODO Auto-generated method stub

et_nameclearFocus();

return false;

}

});

sp_customerlevelsetOnItemSelectedListener(new OnItemSelectedListener() {

@Override

public void onItemSelected(AdapterView<> parent, View view, int position, long id) {

TextView v1 = (TextView) view;

if (v1 != null)

v1setTextColor(ColorBLACK); // 可以随意设置自己要的颜色值

}

@Override

public void onNothingSelected(AdapterView<> parent) {

}

});

// 出生月份

ArrayAdapter<String> monthAdapter = new ArrayAdapter<String>(this, androidRlayoutsimple_spinner_item);

monthAdaptersetDropDownViewResource(androidRlayoutsimple_spinner_dropdown_item);

String monthString;

monthAdapterclear();

position = 0;

for (int i = 0; i < monthListlength; i++) {

monthString = monthList[i];

monthAdapteradd(monthString);

}

sp_month = (Spinner) findViewById(Ridsp_month);

sp_monthsetAdapter(monthAdapter);

sp_monthsetFocusable(true);

sp_monthsetSelection(position);

sp_monthsetOnItemSelectedListener(new OnItemSelectedListener() {

@Override

public void onItemSelected(AdapterView<> parent, View view, int position, long id) {

TextView v1 = (TextView) view;

if (v1 != null)

v1setTextColor(ColorBLACK); // 可以随意设置自己要的颜色值

}

@Override

public void onNothingSelected(AdapterView<> parent) {

}

});

// 客户等级

ArrayAdapter<String> customerlevelAdapter = new ArrayAdapter<String>(this, androidRlayoutsimple_spinner_item);

customerlevelAdaptersetDropDownViewResource(androidRlayoutsimple_spinner_dropdown_item);

String customerlevelString;

customerlevelAdapterclear();

position = 0;

for (int i = 0; i < customerlevelListlength; i++) {

customerlevelString = customerlevelList[i];

customerlevelAdapteradd(customerlevelString);

}

sp_customerlevel = (Spinner) findViewById(Ridsp_customerlevel);

sp_customerlevelsetAdapter(customerlevelAdapter);

sp_customerlevelsetFocusable(true);

sp_customerlevelsetSelection(position);

sp_customerlevelsetOnItemSelectedListener(new OnItemSelectedListener() {

@Override

public void onItemSelected(AdapterView<> parent, View view, int position, long id) {

TextView v1 = (TextView) view;

if (v1 != null)

v1setTextColor(ColorBLACK); // 可以随意设置自己要的颜色值

}

@Override

public void onNothingSelected(AdapterView<> parent) {

}

});

 1Android端代码可以在Eclipse中开发(AndroidStudio没有试,应该也可以)

2Unity3D端代码要在Unity中开发

3Android和Unity3D端,两边都需要加入一些代码从而可以使之关联交互。

4将Android端代码编译成jar文件以插件形式放入到Unity端中

5在Unity中将整个项目Build成apk文件,然后安装到手机或模拟器里运行

本文主要讲解1,2,3。对于4,5建议大家去看雨松MOMO的Unity博客的第17篇和第18篇。

UnityPlay:

在编写Android端和Unity3d端代码前,有必要先了解一下可以使两部分交互的类UnityPlay。

个人理解UnityPlay是个Unity提供给外部交互的一个接口类。

为什么是“个人理解”?这我不得不爆粗口了,TMD官网根本就没有相关的API和文档(如果大家有谁找到一定给我来一份,就当我骂自己了)。

在关联Android时,想拿到UnityPlay以及相关类的jar包可以从下面的地址找到:Unity安装路径\Editor\Data\PlaybackEngines\androidplayer\bin在bin文件夹下有一个classesjar的jar文件,它就是我们想要的。

而在bin同目录下有一个src文件,点击到最后有3个类,分别是UnityPlayerActivityjava,UnityPlayerProxyActivityjava,UnityPlayerNativeActivityjava。前两个打开个后只有一行代码,说的是UnityPlayerActivity和UnityPlayerProxyActivity都继承自UnityPlayerNativeActivity。而打开UnityPlayerNativeActivity中居然有代码,而且我估计这应该是UnityPlayerNativeActivity的源码。

由于关于UnityPlay的资料我只找到这么一个,所以我把UnityPlayerNativeActivity中的代码都贴出来,如果我注解有不对的地方希望大家指正。

/

UnityPlayerActivity,UnityPlayerProxyActivity都继承自UnityPlayerNativeActivity

而UnityPlayerNativeActivity继承自NativeActivity

在该类里定义了一些和ANDROID生命周期相同的回调方法,留给自定义的Activity子类重写。

/

public class UnityPlayerNativeActivity extends NativeActivity

{

//UnityPlayer的引用,并且我们不能改变这个引用变量的名字,它被native code所引用

protected UnityPlayer mUnityPlayer;

protected void onCreate (Bundle savedInstanceState)

{

requestWindowFeature(WindowFEATURE_NO_TITLE);

superonCreate(savedInstanceState);

// 设置显示窗口参数

getWindow()takeSurface(null);

setTheme(androidRstyleTheme_NoTitleBar_Fullscreen);

getWindow()setFormat(PixelFormatRGB_565);

// 创建一个UnityPlayer对象,并赋值给全局的引用变量

mUnityPlayer = new UnityPlayer(this);

//为UnityPlayer设置一些参数

if (mUnityPlayergetSettings ()getBoolean ("hide_status_bar", true))

getWindow ()setFlags (WindowManagerLayoutParamsFLAG_FULLSCREEN,

WindowManagerLayoutParamsFLAG_FULLSCREEN);

int glesMode = mUnityPlayergetSettings()getInt("gles_mode", 1);

boolean trueColor8888 = false;

// UnityPlayerinit()方法需要在将view附加到layout之前调用。它将会调用native code

mUnityPlayerinit(glesMode, trueColor8888);

// 从UnityPlayer中获取到Unity的View视图

View playerView = mUnityPlayergetView();

// 将Unity视图加载到根视图上

setContentView(playerView);

// 使Unity视图获取焦点

playerViewrequestFocus();

}

protected void onDestroy ()

{

// 当Activity结束的时候调用UnityPlayerquit()方法,它会卸载之前调用的native code

mUnityPlayerquit();

superonDestroy();

}

// 下面几个方法都是ANDROID相关回调方法,确保在ANDROID执行相应方法时UnityPlayer也需调用相应方法

protected void onPause()

{

superonPause();

mUnityPlayerpause();

}

protected void onResume()

{

superonResume();

mUnityPlayerresume();

}

public void onConfigurationChanged(Configuration newConfig)

{

superonConfigurationChanged(newConfig);

mUnityPlayerconfigurationChanged(newConfig);

}

public void onWindowFocusChanged(boolean hasFocus)

{

superonWindowFocusChanged(hasFocus);

mUnityPlayerwindowFocusChanged(hasFocus);

}

public boolean dispatchKeyEvent(KeyEvent event)

{

if (eventgetAction() == KeyEventACTION_MULTIPLE)

return mUnityPlayeronKeyMultiple(eventgetKeyCode(), eventgetRepeatCount(), event);

return superdispatchKeyEvent(event);

}

}

看完这个类后就知道了为什么在自定义的Activity中继承了UnityPlayerActivity等类以后,只要重写了onCreate并调用superonCreate()方法后不需要任何其他的代码就会自动的显示出Unity3D的视图。因为初始化Unity视图的代码都在UnityPlayerNativeActivity父类中实现了。

ANDROID端代码:

在写ANDROID代码的时候,一定要导入Unity3D提供给我们的jar包,jar包的位置我在上面说了。引入jar包加入到buildpath中这些最基本的我就不多说了。

要想和Unity交互,我们就不能继承ANDROID提供给我们的Activity,我们需要继承刚才jar包中引入的Unity提供的Activity类,一共有这么3个:

UnityPlayerActivity,UnityPlayerProxyActivity,UnityPlayerNativeActivity。具体区别不知道,因为没有文档,没有API,没有源码(这里再次鄙视一下)。刚才我们看过UnityPlayerNativeActivity的代码(虽然很短,但我觉得这个就是源码),知道UnityPlayerActivity,UnityPlayerProxyActivity都是它的子类,而且最终父类为NativeActivity。所以我们继承Unity提供的最外层的子类是最好的选择,我这里选择的是UnityPlayerActivity,因为名字最简单,觉得该封装的都应该封装好了。

public class MainActivity extends UnityPlayerActivity {

private Button topButton;

private Button bottomButton;

@Override

protected void onCreate(Bundle savedInstanceState) {

superonCreate(savedInstanceState);

// 设置test为我们的根布局

setContentView(Rlayouttest);

// 通过刚才的源码分析,知道mUnityPlayer为一个全局的引用变量,而且已经在父类中设置好了,所以直接拿来用就可以了

View playerView = mUnityPlayergetView();

// 将Unity的视图添加到我们为其准备的父容器中

LinearLayout ll = (LinearLayout) findViewById(RidunityViewLyaout);

lladdView(playerView);

// 上面的button设置监听器

topButton = (Button) findViewById(RidtopButton);

topButtonsetOnClickListener(new ViewOnClickListener() {

@Override

public void onClick(View v) {

//发送消息给Unity端,该函数第一个参数为接受消息的类对象,第二个该类对象用接受消息的方法,第三个参数为传递的消息

//所以下面的意思就为:调用Main Camera下面的Previous方法,传送的消息为空

UnityPlayerUnitySendMessage("Main Camera","Previous","");

}

});

// 为下面的button设置监听器

bottomButton = (Button) findViewById(RidbottomBtn);

bottomButtonsetOnClickListener(new ViewOnClickListener() {

@Override

public void onClick(View v) {

//调用Main Camera下面的Next方法,传送的消息为空

UnityPlayerUnitySendMessage("Main Camera","Next","");

}

});

}

}

最后看一下Android端的布局文件,布局很简单,上下各有一个button按钮,两个按钮中间是Unity的视图。

RecycleView 用法 :

1 [endif]在Gradle中添加

implementation 'comandroidsupport:recyclerview-v7:2602'

2 [endif]在主布局文件里添加RecycleView

3 [endif]创建item布局文件

在电视开发中,需要添加focusable 与 focusableintouchmode 才可以获得焦点。

4 [endif]创建adapter继承RecyclerViewAdapter

5 [endif] 在adapter中添加缺省方法

1) [endif]On create ViewHolder()方法是将item布局加载到recycleView 的方法

View view = LayoutInflater from (parentgetContext())inflate(Rlayout item_2 , parent, false);

创建一个ViewHolder,并添加到ViewHolder里面去,最后返回这个ViewHolder:

ViewHolder holder = new ViewHolder(view);return holder;

2) OnbindViewHolder()是将ViewHolder绑定到RecycleView上面时调用的方法

可在这里做更新View的 *** 作。

3) [endif]GetItemCount 方法为返回数据长度的方法。一般返回值为:

return XXXsize();

4) [endif]在adapter中创建一个viewHolder,继承

 RecyclerViewViewHolder

在这里创建item布局中的控件对象,在public ViewHolder(View itemView)

方法中初始化:

tvItem2 = itemViewfindViewById(Rid tv_item_2 );

6 在adapter 中创建一个数据对象用来接收想要传入的数据,在结构体中接收传入的数据例如:

private List mData;

在Activity中的 *** 作

1 [endif]创建recycleView对象,创建layoutManager(布局管理器)对象,创建adapter对象,创建数据对象

2 实例化recycleView对象,layoutManager对象,adapter对象

RecycleView有几种布局管理器可用,可实现线性,网格,以及瀑布流的界面,以下为线性布局:

mlayoutManager = new LinearLayoutManager(this);

以下为网格布局:

//mlayoutManager = new GridLayoutManager(this,3,GridLayoutManagerHORIZONTAL,false);

3为recycleview 设置布局管理器:

viewRecy2setLayoutManager(mlayoutManager);

4为recycleview设置adapter:

//3 设置数据适配器viewRecy2setAdapter(myAdapter);

如果要在每一个item中添加事件,采取事件回调的方法,其他自定义View的回调皆类似,以下以添加点击事件为例:

1) 在adapter中添加点击事件的接口,并添加接口方法:

public interface onItemClickListener {    void onItemClick(View view, int position);}

2) [endif]在adapter中创建接口实例

private onItemClickListener onItemClickListener;

3) 在adapter创建对应set方法体来接收Activity传入的对象

public void setOnItemClickListener(onItemClickListener onItemClickListener) {    thisonItemClickListener = onItemClickListener;}

4)在onbindViewholde中判断是否设置了监听器

if (onItemClickListener !=null) {

//为ItemView设置监听器

        holdertvItem2setOnClickListener(new ViewOnClickListener() {

@Override

            public void onClick(View v) {

int position =holdergetLayoutPosition();

                onItemClickListeneronItemClick(holdertvItem2, position);

                //onItemClickListeneronItemClick();

            }

});

    }

}

5) 最后在activity中通过adapter对象调用onset方法,实现点击事件

myAdaptersetOnItemClickListener(new MyAdapteronItemClickListener() {

@Override

            public void onItemClick(View view, int position) {

lastPosition =currentPosition;

                currentPosition = position;

//                ToastmakeText(RecycleActivity_2this, "click+" + position, ToastLENGTH_SHORT)show();

                myAdapternotifyItemChanged(currentPosition);

                myAdapternotifyItemChanged(lastPosition);

            }

});

Android TV中RecycleView的Item循环实现

(1) 在TV中遥控器的按键取代了手机的滑动,因此我们要监听遥控器的按键,因此在adapter中的item监听setonkeylistener方法。

并获取item所在位置的position,存到tag里面

holdertvItem2setTag(position);

 

当在第一个Item中按向上键时,position<0,此时我们调用移动到最后一个,同理,当在最后一个时,移动到第一个。

smoothScrollToPosition(getItemCount() - 1)

holdertvItem2setOnKeyListener(new ViewOnKeyListener() {

@Override

            public boolean onKey(View v, int keyCode, KeyEvent event) {

int action = eventgetAction();

//                Loge("---", keyCode + "");

                switch (keyCode) {

case KeyEventKEYCODE_DPAD_UP:

int positionUp = (int) vgetTag();

                        if (action == KeyEventACTION_DOWN) {

if (positionUp <=0) {

recyclerViewsmoothScrollToPosition(getItemCount() -1);

return true;

                            }

}

break;

                    case KeyEventKEYCODE_DPAD_DOWN:

int positionDown = (int) vgetTag();

                        if (action == KeyEventACTION_DOWN) {

if (positionDown >= getItemCount() -1) {

recyclerViewsmoothScrollToPosition(0);

return true;

                            }

}

break;

                }

return false;

            }

});

 

(2) 然后在activity中封装了一个回滚方法来判断按键是否到达底部,并重新获取焦点

public void scroolChange(RecyclerView recyclerView, boolean toFirst, boolean toLast) {

LinearLayoutManager manager = (LinearLayoutManager) recyclerViewgetLayoutManager();

    int lastVisibleItem = managerfindLastCompletelyVisibleItemPosition();

    int firstVisibleItem = managerfindFirstCompletelyVisibleItemPosition();

    int totalItemCount = managergetItemCount();

    //向下滚动,到底部

    if (lastVisibleItem == (totalItemCount -1) && toLast) {

View view = recyclerViewgetChildAt(lastVisibleItem);

        LinearLayoutManager llM = (LinearLayoutManager) recyclerViewgetLayoutManager();

        if (view !=null) {

viewrequestFocus();

        }else if (llMfindViewByPosition(lastVisibleItem) !=null) {

llMfindViewByPosition(lastVisibleItem)requestFocus();

        }else {

recyclerViewrequestFocus();

        }

}

//向上滚动,到顶部

    if (firstVisibleItem ==0 && toFirst) {

View view = recyclerViewgetChildAt(firstVisibleItem);

        LinearLayoutManager llM = (LinearLayoutManager) recyclerViewgetLayoutManager();

        if (view !=null) {

viewrequestFocus();

        }else if (llMfindViewByPosition(firstVisibleItem) !=null) {

llMfindViewByPosition(firstVisibleItem)requestFocus();

        }else {

recyclerViewrequestFocus();

        }

}

}

(3) 最后在recycleView 调用addscrolllistener方法,来监听recycleView的滚动状态

由于setonScrollListener有时回产生空指针,因此建议使用add方法

viewRecy2addOnScrollListener(new RecyclerViewOnScrollListener() {

boolean toLast =false;

            boolean toFirst =false;

            @Override

            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

superonScrollStateChanged(recyclerView, newState);

                if (newState == recyclerViewSCROLL_STATE_IDLE) {

//                    Loge("---", "底部");

                    scroolChange(recyclerView, toFirst, toLast);

                }

}

@Override

            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

superonScrolled(recyclerView, dx, dy);

                if (dy >0) {

toLast =true;

                }else {

toFirst =true;

                }

}

});

Add中包含两个方法,都可以来判断是否到达顶部或底部。至此,实现了Android TV中RecycleView的循环功能。

问题:开发项目账华为mate9测试项目一直正常,当用Remi 5A是,一进入到界面editview就获得了焦点

解决:在EditView的外层layout中添加android:focusable="true" android:focusableInTouchMode="true"

例子:

<LinearLayout

style="@style/FillWrapWidgetStyle"

android:orientation="vertical"

android:background="@color/black"

android:gravity="center_horizontal"

参考: >

以上就是关于如何让edittext在activity起始的时候不自动获得焦点全部的内容,包括:如何让edittext在activity起始的时候不自动获得焦点、unity项目如何导入android项目中成为安卓项目中的一部分、Android TV中实现RecyView循环功能等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9533198.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存