博舍

DiegoAPP–机器人设置,及选择 安卓的机器人在哪里打开设置功能

DiegoAPP–机器人设置,及选择

更多创客作品,请关注笔者网站园丁鸟,搜集全球极具创意,且有价值的创客作品ROS机器人知识请关注,diegorobot业余时间完成的一款在线统计过程分析工具SPC,及SPC知识分享网站qdo

1.App有两个Activity

RobotChooser,作为APP运行起来的Activity,配置为MainAction,为用户呈现一个新增机器人,配置配置机器人的界面ControlApp,在连接到Robot后的主界面,执行控制任务,及RosTopic数据的接收,并显示在界面上,有兴趣的同学可以到https://www.diegorobot.com下载试用。

我们需要在项目的文件中配置两个Activity,并吧RobotChooser配置为Main,如下图所示:2.RobotChooser功能说明RobotChooser为用户进入APP的第一个页面,主要提供如下功能

新增Robot,用户可以通过右上角的加号按钮来添加Robot,一个Robot代表一个RosMasterRobot列表,用户可以添加多个RobotMaster,并列表显示Robot编辑,用户点击修改按钮,即可进入Robot信息的编辑页面,可以修改Masterip,及topic的名称Robot删除,用户也可以点击删除按钮删除RobotRobot在线状态,Robot列表中的信号图标如果是灰色,则表明Robot不在线,否则说明Robot是在线状态,可以连接连接到Robot,当Robot处于在线状态的情况下,可以点击Robot项,直接连接到Robot,后跳转到控制页面

RobotChooser代码主要逻辑说明

RobotChooser继承自AppCompatActivity,并实现了相应的接口,代码如下:

publicclassRobotChooserextendsAppCompatActivityimplementsAddEditRobotDialogFragment.DialogListener,ConfirmDeleteDialogFragment.DialogListener,ListView.OnItemClickListener{/**Keyforwhetherthisisthefirsttimetheapphasbeenlaunched*/publicstaticfinalStringFIRST_TIME_LAUNCH_KEY="FIRST_TIME_LAUNCH";privateRecyclerViewmRecyclerView;privateRecyclerView.AdaptermAdapter;privateShowcaseViewshowcaseView;privateToolbarmToolbar;privateActionBarDrawerTogglemDrawerToggle;//VariablesforkeepingtrackofFragmentsprivateFragmentfragment=null;privateFragmentManagerfragmentManager;privateintfragmentsCreatedCounter=0;//LogtagStringprivatestaticfinalStringTAG="RobotChooser";

在RobotChooser变量声明部分,两个主要的变量是:

mRecyclerView,这个是主要操作的界面视图类mAdapter,这个类是Robot工具item,删除,编辑,连接到Robot的主要功能实现,对应的文件是Core/RobotInfoAdaptershowcaseView,使用ShowcaseView实现在Robot列表中还没有添加Robot的情况下,实现操作引导界面AndroidAPPActivity的初始化代码一般放在onCreate(),RobotChooser的代码如下:

publicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);try{this.setContentView(R.layout.robot_chooser);}catch(Exceptione){}mRecyclerView=(RecyclerView)findViewById(R.id.robot_recycler_view);RecyclerView.LayoutManagermLayoutManager=newLinearLayoutManager(this);mRecyclerView.setItemAnimator(newDefaultItemAnimator());mRecyclerView.setLayoutManager(mLayoutManager);mToolbar=(Toolbar)findViewById(R.id.robot_chooser_toolbar);setSupportActionBar(mToolbar);RobotStorage.load(this);if(getActionBar()!=null){getActionBar().setDisplayHomeAsUpEnabled(true);getActionBar().setHomeButtonEnabled(true);}//AdapterforcreatingthelistofRobotoptionsmAdapter=newRobotInfoAdapter(this,RobotStorage.getRobots());mRecyclerView.setAdapter(mAdapter);ScheduledExecutorServiceworker=Executors.newSingleThreadScheduledExecutor();//CheckwhetherthisisthefirsttimetheapphasbeenlaunchedonthisdevicefinalbooleanisFirstLaunch=PreferenceManager.getDefaultSharedPreferences(this).getBoolean(FIRST_TIME_LAUNCH_KEY,true);//Delaytheinitialtutorialalittlebit//ThismakessuretheviewgetsagoodreferencetotheUIlayoutpositionsRunnabletask=newRunnable(){publicvoidrun(){runOnUiThread(newRunnable(){@Overridepublicvoidrun(){try{if(RobotStorage.getRobots().size()==0&&isFirstLaunch){//ShowinitialtutorialmessageshowcaseView=newShowcaseView.Builder(RobotChooser.this).setTarget(newToolbarActionItemTarget(mToolbar,R.id.action_add_robot)).setStyle(R.style.CustomShowcaseTheme2).hideOnTouchOutside().blockAllTouches()//.singleShot(0)Canusethisinsteadofmanuallysavinginpreferences.setContentTitle(R.string.splash_add_robot_title).setContentText(R.string.splash_add_robot_text).build();//GetreadytoshowtutorialmessagewhenuseraddsarobotsetupNextTutorialMessage();}}catch(Exceptionignore){}}});}};worker.schedule(task,1,TimeUnit.SECONDS);}

在这段代码中首先指定了Activity对应的resid,初始化了mRecyclerView等变量,这里需要关注的是RobotStorage.load(this)载入了已经配置好的Robot信息,返回一个Robot列表,并显示在主界面上。

isFirstLaunch变量定义了用户是不是第一次打开APP,同时通过runOnUiThread运行一个独立的线程来执行ShowCaseView,实现功能引导,显示功能引导界面的条件是用户第一次使用,或者Robotlist中没有Robot。

RobotChooser其他部分代码主要是正对Robot的增删改操作,及一些消息的传递,这里不在讲解。

RobotInfoAdapter代码主要逻辑讲解

在Robotchooser界面针对当Robot的操作都是在RobotInfoAdapter中实现的,此文件位于Core文件夹下。其中内嵌了类ViewHolder来指定res,同时实现操作,其代码如下:

publicViewHolder(Viewv){super(v);v.setClickable(true);v.setOnClickListener(this);mRobotNameTextView=(TextView)v.findViewById(R.id.robot_name_text_view);mMasterUriTextView=(TextView)v.findViewById(R.id.master_uri_text_view);mEditButton=(ImageButton)v.findViewById(R.id.robot_edit_button);mEditButton.setOnClickListener(this);mDeleteButton=(ImageButton)v.findViewById(R.id.robot_delete_button);mDeleteButton.setOnClickListener(this);mImageView=(ImageView)v.findViewById(R.id.robot_wifi_image);mImageView.setImageResource(R.mipmap.wifi_0);Timert=newTimer();t.scheduleAtFixedRate(newTimerTask(){@Overridepublicvoidrun(){try{intposition=getAdapterPosition();finalRobotInfoinfo=mDataset.get(position);//mImageView.setLayoutParams(newActionBar.LayoutParams(mEditButton.getHeight(),mEditButton.getHeight()));if(isPortOpen(info.getUri().getHost(),info.getUri().getPort(),10000)){activity.runOnUiThread(newRunnable(){@Overridepublicvoidrun(){mImageView.setImageResource(R.mipmap.wifi_4);}});}else{activity.runOnUiThread(newRunnable(){@Overridepublicvoidrun(){mImageView.setImageResource(R.mipmap.wifi_0);}});}Thread.sleep(10000);}catch(Exceptionignore){}}},1000,15000);}/***HandlesclicksontheRobotInfoAdapter.ViewHolder.**@paramvTheclickedView.Canbeeithertheeditbutton,deletebutton,ortheadapteritself,*inwhichcaseaconnectionisinitiatedtotheRobotInfocontainedinthisAdapter*/@OverridepublicvoidonClick(Viewv){intposition=getAdapterPosition();Bundlebundle;finalRobotInfoinfo=mDataset.get(position);switch(v.getId()){caseR.id.robot_edit_button:AddEditRobotDialogFragmenteditRobotDialogFragment=newAddEditRobotDialogFragment();bundle=newBundle();info.save(bundle);bundle.putInt(AddEditRobotDialogFragment.POSITION_KEY,position);editRobotDialogFragment.setArguments(bundle);editRobotDialogFragment.show(activity.getSupportFragmentManager(),"editrobotialog");break;caseR.id.robot_delete_button:ConfirmDeleteDialogFragmentconfirmDeleteDialogFragment=newConfirmDeleteDialogFragment();bundle=newBundle();bundle.putInt(ConfirmDeleteDialogFragment.POSITION_KEY,position);bundle.putString(ConfirmDeleteDialogFragment.NAME_KEY,info.getName());confirmDeleteDialogFragment.setArguments(bundle);confirmDeleteDialogFragment.show(activity.getSupportFragmentManager(),"deleterobotdialog");break;default:FragmentManagerfragmentManager=activity.getFragmentManager();ConnectionProgressDialogFragmentf=newConnectionProgressDialogFragment(info);f.show(fragmentManager,"ConnectionProgressDialog");break;}}}

在此类中,除了在开头部分指定了资源,主要有两部功能:

启动一个定时器任务,每10000毫秒检查一次Robot的在线状态,并同时更新界面的在线状态图标处理onClick事件,根据用户点击的按钮执行相应的操作,当用户点击的是整个Robot的item时,则通过RobotinforAdapter的run函数跳转到ControlAppAction,界面切换为Robot的控制界面。

privatevoidrun(){thread=newThread(newRunnable(){@Overridepublicvoidrun(){try{if(!isPortOpen(INFO.getUri().getHost(),INFO.getUri().getPort(),10000)){thrownewException(getActivity().getString(R.string.cannot_connect_ros));}finalIntentintent=newIntent(activity,ControlApp.class);//!!!----EVILUSEOFSTATICVARIABLE----!!////ShouldnotbedoingthisbutthereisnootherwaythatIcansee-MichaelControlApp.ROBOT_INFO=INFO;dismiss();activity.runOnUiThread(newRunnable(){@Overridepublicvoidrun(){activity.startActivity(intent);}});}catch(finalNetworkOnMainThreadExceptione){dismiss();activity.runOnUiThread(newRunnable(){@Overridepublicvoidrun(){Toast.makeText(activity,"InvalidMasterURI",Toast.LENGTH_LONG).show();}});}catch(InterruptedExceptione){//IgnoreLog.d(TAG,"interrupted");}catch(finalExceptione){if(ConnectionProgressDialogFragment.this.getFragmentManager()!=null)dismiss();activity.runOnUiThread(newRunnable(){@Overridepublicvoidrun(){Toast.makeText(activity,e.getMessage(),Toast.LENGTH_LONG).show();}});}}});thread.start();}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

上一篇

下一篇