首页 文章 精选 留言 我的

精选列表

搜索[网站开发],共10000篇文章
优秀的个人博客,低调大师

Android UI开发第二十六篇——Fragment间的通信

为了重用Fragment的UI组件,创建的每个Fragment都应该是自包含的、有它自己的布局和行为的模块化组件。一旦你定义了这些可重用的Fragment,你就可以把它们跟一个Activity关联,并把它们跟应用程序的逻辑相连来实现全部的组合式UI。 现实中我们经常想要一个Fragment跟另一个Fragment进行通信,例如,要基于一个用户事件来改变内容。所有的Fragment间的通信都是通过跟关联的Activity来完成的。另个Fragment不应该直接通信。也就是说Fragment间不直接通信,通过Activity转一下,按java常规,转一下多是使用Interface实现的。 定义Interface 为了让Fragment跟它的Activity通信,你可以在Fragment类中定义一个接口,并在它所属的Activity中实现该接口。Fragment在它的onAttach()方法执行期间捕获该接口的实现,然后就可以调用接口方法,以便跟Activity通信。 以下是Fragment跟Activity通信的示例: public class HeadlinesFragment extends ListFragment { OnHeadlineSelectedListener mCallback; // Container Activity must implement this interface public interface OnHeadlineSelectedListener { public void onArticleSelected(int position); } @Override public void onAttach(Activity activity) { super.onAttach(activity); // This makes sure that the container activity has implemented // the callback interface. If not, it throws an exception try { mCallback = (OnHeadlineSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnHeadlineSelectedListener"); } } ... } 现在,这个Fragment就可以通过调用OnHealdlineSelectedListener接口实例mCallback的onArticleSelected()方法(或其他的接口中的方法)给Activity发送消息。 例如,在Fragment中的下列方法会用户点击列表项时被调用。该Fragment使用回调接口把该事件发送给它的父Activity。 @Override public void onListItemClick(ListView l, View v, int position, long id) { // Send the event to the host activity mCallback.onArticleSelected(position); } 实现Interface 为了从Fragment中接收事件回调,包含Fragment的Activity必须实现Fragment类中定义的接口。 例如,下面Activity实现了上面示例中定义的接口: public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(int position) { // The user selected the headline of an article from the HeadlinesFragment // Do something here to display that article } } 把消息传递给另一个Fragment 通过使用findFragmentById()方法捕获Fragment实例,宿主Activity可以把消息发送给该Fragment,然后直接调用该Fragment的公共方法。 例如,上面的示例,Activty通过Interface的实现方法,传递数据到另一个Fragment。 public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(int position) { // The user selected the headline of an article from the HeadlinesFragment // Do something here to display that article ArticleFragment articleFrag = (ArticleFragment) getSupportFragmentManager().findFragmentById(R.id.article_fragment); if (articleFrag != null) { // If article frag is available, we're in two-pane layout... // Call a method in the ArticleFragment to update its content articleFrag.updateArticleView(position); } else { // Otherwise, we're in the one-pane layout and must swap frags... // Create fragment and give it an argument for the selected article ArticleFragment newFragment = new ArticleFragment(); Bundle args = new Bundle(); args.putInt(ArticleFragment.ARG_POSITION, position); newFragment.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack so the user can navigate back transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // Commit the transaction transaction.commit(); } } } Fragment中使用左右滑动菜单中应用到了Fragment间的通信 参考:http://developer.android.com/training/basics/fragments/communicating.html 本文转自xyz_lmn51CTO博客,原文链接:http://blog.51cto.com/xyzlmn/1230753,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android UI开发第二十七篇——实现左右划出菜单

年前就想写左右滑动菜单,苦于没有时间,一直拖到现在,这篇代码实现参考了网上流行的SlidingMenu,使用的FrameLayout布局,不是扩展的HorizontalScrollView。 程序中自定义了菜单view:SlidingView,继承自ViewGroup,使用FrameLayout布局。重写了onInterceptTouchEvent(MotionEvent ev)方法实现ontouch的分发拦截,重写了onTouchEvent(MotionEvent ev)方法,实现左右滑动。 public class SlidingView extends ViewGroup { private FrameLayout mContainer; private Scroller mScroller; private VelocityTracker mVelocityTracker; private int mTouchSlop; private float mLastMotionX; private float mLastMotionY; private static final int SNAP_VELOCITY = 1000; private View mLeftView; private View mRightView; public SlidingView(Context context) { super(context); init(); } public SlidingView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public SlidingView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mContainer.measure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int width = r - l; final int height = b - t; mContainer.layout(0, 0, width, height); } private void init() { mContainer = new FrameLayout(getContext()); mContainer.setBackgroundColor(0xff000000); mScroller = new Scroller(getContext()); mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); super.addView(mContainer); } public void setView(View v) { if (mContainer.getChildCount() > 0) { mContainer.removeAllViews(); } mContainer.addView(v); } @Override public void scrollTo(int x, int y) { super.scrollTo(x, y); postInvalidate(); } @Override public void computeScroll() { if (!mScroller.isFinished()) { if (mScroller.computeScrollOffset()) { int oldX = getScrollX(); int oldY = getScrollY(); int x = mScroller.getCurrX(); int y = mScroller.getCurrY(); if (oldX != x || oldY != y) { scrollTo(x, y); } // Keep on drawing until the animation has finished. invalidate(); } else { clearChildrenCache(); } } else { clearChildrenCache(); } } private boolean mIsBeingDragged; /** * 实现了ontouch的分发拦截 */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final int action = ev.getAction(); final float x = ev.getX(); final float y = ev.getY(); switch (action) { case MotionEvent.ACTION_DOWN: mLastMotionX = x; mLastMotionY = y; mIsBeingDragged = false; break; case MotionEvent.ACTION_MOVE: final float dx = x - mLastMotionX; final float xDiff = Math.abs(dx); final float yDiff = Math.abs(y - mLastMotionY); if (xDiff > mTouchSlop && xDiff > yDiff) { mIsBeingDragged = true; mLastMotionX = x; } Log.d("Sliding", "SlidingView_Touch:"+x+"|"+y); Log.d("Sliding", "SlidingView_Touch:"+xDiff+"|"+mTouchSlop+"|"+yDiff+"|"+mLastMotionY); Log.d("Sliding", "SlidingView_Touch:"+mIsBeingDragged); break; } return mIsBeingDragged; } @Override public boolean onTouchEvent(MotionEvent ev) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); final int action = ev.getAction(); final float x = ev.getX(); final float y = ev.getY(); switch (action) { case MotionEvent.ACTION_DOWN: if (!mScroller.isFinished()) { mScroller.abortAnimation(); } mLastMotionX = x; mLastMotionY = y; if (getScrollX() == -getLeftMenuWidth() && mLastMotionX < getLeftMenuWidth()) { return false; } if (getScrollX() == getRightMenuWidth() && mLastMotionX > getLeftMenuWidth()) { return false; } break; case MotionEvent.ACTION_MOVE: if (mIsBeingDragged) { enableChildrenCache(); final float deltaX = mLastMotionX - x; mLastMotionX = x; float oldScrollX = getScrollX(); float scrollX = oldScrollX + deltaX; if (deltaX < 0 && oldScrollX < 0) { // left view final float leftBound = 0; final float rightBound = -getLeftMenuWidth(); if (scrollX > leftBound) { scrollX = leftBound; } else if (scrollX < rightBound) { scrollX = rightBound; } } else if (deltaX > 0 && oldScrollX > 0) { // right view final float rightBound = getRightMenuWidth(); final float leftBound = 0; if (scrollX < leftBound) { scrollX = leftBound; } else if (scrollX > rightBound) { scrollX = rightBound; } } scrollTo((int) scrollX, getScrollY()); if (scrollX > 0) { mLeftView.setVisibility(View.GONE); mLeftView.clearFocus(); mRightView.setVisibility(View.VISIBLE); mRightView.requestFocus(); } else { mLeftView.setVisibility(View.VISIBLE); mLeftView.requestFocus(); mRightView.setVisibility(View.GONE); mRightView.clearFocus(); } } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (mIsBeingDragged) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000); int velocityX = (int) velocityTracker.getXVelocity(); velocityX = 0; int oldScrollX = getScrollX(); int dx = 0; if (oldScrollX < 0) { // 左边 if (oldScrollX < -getLeftMenuWidth() / 2 || velocityX > SNAP_VELOCITY) { // 左侧页面划出 dx = -getLeftMenuWidth() - oldScrollX; } else if (oldScrollX >= -getLeftMenuWidth() / 2 || velocityX < -SNAP_VELOCITY) { // 左侧页面关闭 dx = -oldScrollX; } } else { // 右边 if (oldScrollX > getRightMenuWidth() / 2 || velocityX < -SNAP_VELOCITY) { // 右侧页面划出 dx = getRightMenuWidth() - oldScrollX; } else if (oldScrollX <= getRightMenuWidth() / 2 || velocityX > SNAP_VELOCITY) { // 右侧页面关闭 dx = -oldScrollX; } } smoothScrollTo(dx); clearChildrenCache(); } break; } if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } return true; } private int getLeftMenuWidth() { if (mLeftView == null) { return 0; } return mLeftView.getWidth(); } private int getRightMenuWidth() { if (mRightView == null) { return 0; } return mRightView.getWidth(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } public View getRightView() { return mRightView; } public void setRightView(View mRightView) { this.mRightView = mRightView; } public View getMenuView() { return mLeftView; } public void setLeftView(View mLeftView) { this.mLeftView = mLeftView; } void toggle() { int menuWidth = mLeftView.getWidth(); int oldScrollX = getScrollX(); if (oldScrollX == 0) { smoothScrollTo(-menuWidth); } else if (oldScrollX == -menuWidth) { smoothScrollTo(menuWidth); } } /** * 打开(关闭)左侧页面 */ public void showLeftView() { mLeftView.setVisibility(View.VISIBLE); mRightView.setVisibility(View.GONE); int menuWidth = mLeftView.getWidth(); int oldScrollX = getScrollX(); if (oldScrollX == 0) { smoothScrollTo(-menuWidth); } else if (oldScrollX == -menuWidth) { smoothScrollTo(menuWidth); } } /** * 打开(关闭)右侧页面 */ public void showRightView() { mLeftView.setVisibility(View.GONE); mLeftView.clearFocus(); mRightView.setVisibility(View.VISIBLE); mRightView.requestFocus(); int menuWidth = mRightView.getWidth(); int oldScrollX = getScrollX(); if (oldScrollX == 0) { smoothScrollTo(menuWidth); } else if (oldScrollX == menuWidth) { smoothScrollTo(-menuWidth); } } /** * 显示中间页面 */ public void showCenterView() { int menuWidth = mRightView.getWidth(); int oldScrollX = getScrollX(); if (oldScrollX == menuWidth) { showRightView(); } else if (oldScrollX == -menuWidth) { showLeftView(); } } void smoothScrollTo(int dx) { int duration = 500; int oldScrollX = getScrollX(); mScroller.startScroll(oldScrollX, getScrollY(), dx, getScrollY(), duration); invalidate(); } void enableChildrenCache() { final int count = getChildCount(); for (int i = 0; i < count; i++) { final View layout = (View) getChildAt(i); layout.setDrawingCacheEnabled(true); } } void clearChildrenCache() { final int count = getChildCount(); for (int i = 0; i < count; i++) { final View layout = (View) getChildAt(i); layout.setDrawingCacheEnabled(false); } } } SlidingMenu对SlidingView做了进一步封装处理: public class SlidingMenu extends RelativeLayout { private SlidingView mSlidingView; private View mLeftView; private View mRightView; // menu width private int alignScreenWidth; public SlidingMenu(Context context) { super(context); } public SlidingMenu(Context context, AttributeSet attrs) { super(context, attrs); } public SlidingMenu(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setAlignScreenWidth(int alignScreenWidth) { this.alignScreenWidth = alignScreenWidth; } public void setLeftView(View view) { LayoutParams behindParams = new LayoutParams(alignScreenWidth, LayoutParams.MATCH_PARENT); addView(view, behindParams); mLeftView = view; } public void setRightView(View view) { LayoutParams behindParams = new LayoutParams(alignScreenWidth, LayoutParams.MATCH_PARENT); behindParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); addView(view, behindParams); mRightView = view; } public void setCenterView(View view) { LayoutParams aboveParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); mSlidingView = new SlidingView(getContext()); addView(mSlidingView, aboveParams); mSlidingView.setView(view); mSlidingView.invalidate(); mSlidingView.setLeftView(mLeftView); mSlidingView.setRightView(mRightView); } public void showLeftView() { mSlidingView.showLeftView(); } public void showRightView() { mSlidingView.showRightView(); } public void showCenterView() { mSlidingView.showCenterView(); } } SlidingMenu的使用代码 public class SlidingActivity extends Activity implements OnClickListener{ SlidingMenu mSlidingMenu; @Override protected void onCreate(Bundle arg0) { super.onCreate(arg0); setContentView(R.layout.main); DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); mSlidingMenu = (SlidingMenu) findViewById(R.id.slidingMenu); mSlidingMenu.setAlignScreenWidth((dm.widthPixels / 5) * 2); View leftView=getLayoutInflater().inflate(R.layout.left_menu, null); View rightView=getLayoutInflater().inflate(R.layout.right_menu, null); View centerView=getLayoutInflater().inflate(R.layout.center, null); mSlidingMenu.setLeftView(leftView); mSlidingMenu.setRightView(rightView); mSlidingMenu.setCenterView(centerView); Button showLeftMenu=(Button)centerView.findViewById(R.id.center_left_btn); showLeftMenu.setOnClickListener(this); Button showRightMenu=(Button)centerView.findViewById(R.id.center_right_btn); showRightMenu.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.center_left_btn: mSlidingMenu.showLeftView(); break; case R.id.center_right_btn: mSlidingMenu.showRightView(); break; default: break; } } } 代码:http://download.csdn.net/detail/xyz_lmn/5109965 本文转自xyz_lmn51CTO博客,原文链接:http://blog.51cto.com/xyzlmn/1230751,如需转载请自行联系原作者

优秀的个人博客,低调大师

ios开发学习-弹出视图(Popup View) 效果源码分享--系列教程4

Popup TextView 介绍:实现弹出文字输入框的效果。类似Facebook应用中弹出的状态输入框一样。http://ios.itmdc.com/thread-1937-1-11.htmlPop List View 介绍:实现一个弹出视图,弹出的视图上加上列表。可以取代UIActionSheet,使界面更加灵活美观。视图弹出和消失的动画都非常棒。http://ios.itmdc.com/thread-1941-1-11.htmlBlock Alerts and ActionSheets 介绍:实现各种各样的alert和 UIActionSheet和UIAlertView效果。比如,在UIAlertView中加入文字输入框,同时显示UIActionSheet和UIAlertView,显示多个UIAlertView等等。并且UIAlertView的出现和消失的动画都比默认的效果好很多(有一种弹簧的效果)。http://ios.itmdc.com/thread-1946-1-11.htmlNotification Manager 介绍:在窗口顶端弹出自定义的提示视图(notification View)。弹出的notification view可以自动隐藏。如果有多个notification view,则进行排队,按顺序显示。可用于显示当前app的状态,用户操作的提示、提醒通知等等。这种notification view比UIAlertView来得友好。http://ios.itmdc.com/thread-1948-1-11.htmlInfo Bar 介绍:用于当后台有任务运行时,或者用户进行了某些耗时较长的操作时,用于给用户显示提示信息。显示的提示信息位置位于tab bar的上方,自动显示,并且自动隐藏。提示信息的显示是异步的,也就是不会导致程序停滞。在效果图中,“Action From View 1”便是显示的提示信息,可以自动隐藏。http://ios.itmdc.com/thread-1951-1-11.htmlUITextField within Alert Prompt 介绍:在弹出对话框(Alert dialogue)中加入登录框。即在UIAlertView中加入文字输入框(UITextField)。http://ios.itmdc.com/thread-1954-1-11.htmlHidden Option Panel 介绍:实现可以隐藏的面板。这个面板一般位于窗口的下方。起初只是一个箭头按钮,当用户点击箭头按钮时,面板会向上缓慢滑动出来。http://ios.itmdc.com/thread-1957-1-11.htmlTableView Within Alert 介绍:在弹出对话框(Alert dialogue)中加入列表(UITableView)。http://ios.itmdc.com/thread-1959-1-11.htmlPopTip View 介绍:实现各种弹出消息/tips的效果。点击任意控件,按钮,导航条按钮,工具条按钮(UIBarButtonItem),都会弹出消息气泡。弹出的气泡会自动定位在相应的按钮旁边,并且有小箭头指向这个按钮。气泡的文字和颜色可以自定义。http://ios.itmdc.com/thread-1962-1-11.html 本文转自qianqianlianmeng博客园博客,原文链接:http://www.cnblogs.com/aimeng/archive/2012/12/07/2807900.html ,如需转载请自行联系原作者

优秀的个人博客,低调大师

ios开发学习-弹出视图(Popup View) 效果源码分享--系列教程2

Drop Down Menu 介绍:实现弹出下拉菜单效果。当点击菜单某个选项时,菜单又会收缩隐藏回去。http://ios.itmdc.com/thread-1881-1-12.html Codex Popup List 介绍:利用WEPopup类库实现弹出列表视图效果。弹出的视图会自动定位在相应的按钮旁边,并且有小箭头指向这个按钮。可以在弹出列表视图上添加文字、图片等。仅支持ARC以及iOS 5.0以上。http://ios.itmdc.com/thread-1882-1-12.html Push Back Animation 介绍:实现新视图弹出时,之前的视图变淡、缩小(即后退为背景视图)的动画效果。http://ios.itmdc.com/thread-1885-1-12.html NotiView 介绍:实现弹出消息视图效果。弹出的视图从界面上方进入,然后自动从界面右方出去。可以自定义弹出视图的icon,颜色,文字,运动方向等等。http://ios.itmdc.com/thread-1887-1-12.html CMActionSheet 介绍:实现特殊效果的UIActionSheet。ActionSheet弹出到最后会有一种弹跳(Bounce)的效果。http://ios.itmdc.com/thread-1888-1-12.html TSPopover 介绍:实现各种弹出视图效果。弹出的视图会自动定位在相应的按钮旁边,并且有小箭头指向这个按钮。可以在弹出视图上添加按钮、列表等控件。只支持iOS5.0,只支持ARC模式。http://ios.itmdc.com/thread-1889-1-12.html XYAlertView 介绍:自定义AlertView/LoadingView,包括背景颜色、文字等等,支持队列显示,即可以连续显示多个AlertView。http://ios.itmdc.com/thread-1892-1-12.html JSNotifier 介绍:实现在界面底部弹出消息通知框(Notification View),弹出的消息框可以加载png图片和Activity Indicatior,并且可以自动隐藏http://ios.itmdc.com/thread-1893-1-12.html 本文转自qianqianlianmeng博客园博客,原文链接:http://www.cnblogs.com/aimeng/archive/2012/12/09/2810024.html ,如需转载请自行联系原作者

优秀的个人博客,低调大师

开发小间距、进军安防市场 绝不能忽略这个问题!

近年来,随着与安防产业密切相关的平安城市、智能交通建设等政策的进一步实施,以及公众安防意识的增强,特别是监控领域,随着监控摄像机的采集、编码、传输等前段产品和技术的不断升级,对后端设备特别是大屏显示这一块的硬件要求也越来越高,使得大屏幕显示产业在安防领域的应用保持了较好的增长势头,尤其是小间距LED,凭借着超强的先天产品优势,以及后天的技术进步,这一两年里迅速成为安防显示领域一颗耀眼的新星,并且表现出强大的持续发展力,前景十分可观。 众所周知,由于使用环境和应用场合的特殊性,安防领域对监控大屏产品和技术提出了近乎苛刻的要求。比如高分辨率的精细化显示,低亮度情况下高灰度还原显示、高刷新率、高一致性与均匀性、低噪音、低散热等等,甚至对长时间持续观看的舒适性都提出了很高的要求。尤其是清晰度要求越来越高高,这也是之前在室内监控领域LED显示产品必过不LCD等产品的一大重要原因,然而小间距的发展,不仅完美解决了清晰度的问题,同时LED显示产品的无缝拼接、一致性强等优势更加受到安防监控市场的欢迎。 此外,智能化也是当前安防显示市场的最大的产品需求之一。随着安防产业很多产品不断走向智能化,作为显示终端的大屏,智能化也是必然趋势。尤其是随着人脸识别、大数据分析等技术的进步,小间距LED想要在安防产业大展宏图,产品智能化就必须跟上前端产品的发展脚步。 近年来,随着LED产业链厂家纷纷加大研发力度,不断在小间距LED产品、技术等方面实现创新,并且从IC、芯片、封装、箱体、控制器、电源等都推出了适用于安防显示领域的小间距、微小间距专业化产品,为小间距LED在安防显示领域的大力发展打下了一定的产品基础,相信未来LED小间距显示屏如果能在高清和智能化方面有更大突破,产品竞争优势将会得到进一步体现,但这些还远远不够。 畅游安防蓝海,除了产品,更需提升整体应用水平: 安防监控市场作为LED显示大屏幕显示的高端市场,不单单是提供优秀的产品就可以,在整体应用上也有着严苛的要求,因此LED屏企必须拥有能为不同类型的客户提供定制化控制室、指挥中心、调度中心等不同运用场景的显示解决方案,并且能以成套的系统,完整的适宜方案呈现在用户面前,同时能更好的为客户提供后续服务,才能够在安防显示市场站稳脚跟并取得发展。 本文转自d1net(转载)

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册