草庐IT

android - 如何在 android 上的选项卡布局上动画覆盖编辑框?

coder 2023-12-11 原文

我想实现这个动画,即搜索编辑框覆盖选项卡布局,我必须告诉我,我在父布局上尝试了这段代码 android:animateLayoutChanges="true" 并设置View.GONE 的选项卡布局可见性,但它只是动画向上移动选项卡,而不是搜索框覆盖选项卡布局。

最佳答案

我制作了一个看起来像您的快速虚拟应用程序,并尝试实现您在动画中显示的内容。看下面的效果(你可以让它更流畅优雅):

这是一种有点棘手的做法,我就是这样做的。我在这里发布我的整个代码:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.pabhinav.testapp3">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


主 Activity .java

package com.pabhinav.testapp3;

import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LinearInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import static com.pabhinav.testapp3.R.id.container;

public class MainActivity extends AppCompatActivity implements PlaceholderFragment.OnSearchBoxClick{

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link FragmentPagerAdapter} derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    private SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    private ViewPager mViewPager;

    /**
     * Search Box in activity.
     */
    private RelativeLayout dummySearchBox;

    private LinearLayout topSearchBox;

    /**
     * Overlay View appears when search box is clicked.
     */
    private View overlay;

    /**
     * Back button image view for top search box
     */
    private ImageView backButtonSearchBox;

    /**
     * PlaceHolderFragment saved only for second tab,
     * which has search box.
     */
    private PlaceholderFragment placeholderFragment;

    private float xDelta, yDelta;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
        getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));
        overlay = findViewById(R.id.overlay_whole_page);
        backButtonSearchBox = (ImageView)findViewById(R.id.search_icon);

        // Consume touch event, so that it does not pass to parent views.
        // This is done to block swipe events of tab layout, once search
        // box is clicked.
        overlay.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return true;
            }
        });

        // TabLayout and ViewPager.
        final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        mViewPager = (ViewPager) findViewById(container);
        dummySearchBox = (RelativeLayout)findViewById(R.id.dummy_search_box);
        topSearchBox = (LinearLayout)findViewById(R.id.top_search_box);

        // Set up the ViewPager with the sections adapter.
        mViewPager.setAdapter(mSectionsPagerAdapter);
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

            @Override
            public void onPageSelected(int position) {
                for (int i = 0; i < tabLayout.getTabCount(); i++) {
                    if(i == position){
                        tabLayout.getTabAt(i).setIcon(getTabIconHighlighted(i));
                    } else {
                        tabLayout.getTabAt(i).setIcon(getTabIconUnhighlighted(i));
                    }
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {}
        });

        // Setup viewpager with tablayout and also set up icons of each tabs :
        tabLayout.setupWithViewPager(mViewPager);
        for(int i = 0; i<tabLayout.getTabCount(); i++){

            // Set first tab highlighted :
            if(i == 0){
                tabLayout.getTabAt(i).setIcon(getTabIconHighlighted(i));
            } else {
                tabLayout.getTabAt(i).setIcon(getTabIconUnhighlighted(i));
            }
        }

        // Back Button in top search box clicked.
        backButtonSearchBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                overlay.setVisibility(View.INVISIBLE);
                dummySearchBox.setVisibility(View.VISIBLE);
                topSearchBox.setVisibility(View.INVISIBLE);

                AnimationSet animSet = new AnimationSet(true);
                animSet.setFillAfter(false);
                animSet.setDuration(150);
                animSet.setInterpolator(new LinearInterpolator());
                TranslateAnimation translate = new TranslateAnimation(-xDelta, 0, -yDelta, 0);
                animSet.addAnimation(translate);
                ScaleAnimation scale = new ScaleAnimation(1.2f, 1f, 1.2f, 1f);
                animSet.addAnimation(scale);
                dummySearchBox.startAnimation(animSet);
                animSet.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        placeholderFragment.showSearchLayout();
                        dummySearchBox.setVisibility(View.INVISIBLE);
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {

                    }
                });
            }
        });
    }

    private int getTabIconUnhighlighted(int position){
        switch (position){
            case 0 : return R.drawable.ic_home_black_24dp;
            case 1 : return R.drawable.ic_search_black_24dp;
            case 2 : return R.drawable.ic_heart_black_24dp;
            case 3 : return R.drawable.ic_view_headline_black_24dp;
        }
        return -1;
    }

    private int getTabIconHighlighted(int position){
        switch(position){
            case 0 : return R.drawable.ic_home_highlighted_24dp;
            case 1 : return R.drawable.ic_search_highlighted_24dp;
            case 2 : return R.drawable.ic_heart_highlighted_24dp;
            case 3 : return R.drawable.ic_view_headline_highlighted_24dp;
        }
        return -1;
    }

    /**
     * This event is when search box from fragment is clicked,
     * need to animate the search box present in activity
     * to reach the top of activity display.
     */
    @Override
    public void onClick() {
        dummySearchBox.setVisibility(View.VISIBLE);
        dummySearchBox.clearFocus();
        ((EditText)findViewById(R.id.search_edit_text)).clearFocus();
        performAnimation(dummySearchBox);
    }

    public void performAnimation(final RelativeLayout dummySearchBox){

        if(xDelta == 0 && yDelta == 0){
            DisplayMetrics dm = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(dm);
            int[] originalPos = new int[2];
            dummySearchBox.getLocationOnScreen(originalPos);

            xDelta = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 18, getResources().getDisplayMetrics());
            yDelta = originalPos[1] - TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, getResources().getDisplayMetrics());;
        }

        AnimationSet animSet = new AnimationSet(true);
        animSet.setFillAfter(false);
        animSet.setDuration(200);
        animSet.setInterpolator(new LinearInterpolator());
        TranslateAnimation translate = new TranslateAnimation( 0, -1*xDelta, 0, -1*yDelta);
        animSet.addAnimation(translate);
        ScaleAnimation scale = new ScaleAnimation(1f, 1.15f, 1f, 1.15f);
        animSet.addAnimation(scale);
        dummySearchBox.startAnimation(animSet);
        animSet.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {

                topSearchBox.setVisibility(View.VISIBLE);
                dummySearchBox.setVisibility(View.INVISIBLE);
                overlay.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        public static final String ARG_SECTION_NUMBER = "section_number";

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment.
            PlaceholderFragment placeholderFragment = new PlaceholderFragment();
            placeholderFragment.setOnSearchBoxClick(MainActivity.this);
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, position + 1);
            placeholderFragment.setArguments(args);
            if(position == 1){
                MainActivity.this.placeholderFragment = placeholderFragment;
            }
            return placeholderFragment;
        }

        @Override
        public int getCount() {
            // Show 4 total pages.
            return 4;
        }
    }
}

PlaceholderFragment.java

package com.pabhinav.testapp3;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

/**
 * @author pabhinav
 */

public class PlaceholderFragment extends Fragment {

    private LinearLayout searchLayout;

    public PlaceholderFragment() {
    }

    private OnSearchBoxClick onSearchBoxClick;
    public void setOnSearchBoxClick(OnSearchBoxClick onSearchBoxClick){
        this.onSearchBoxClick = onSearchBoxClick;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        int sectionNumber = getArguments().getInt(MainActivity.SectionsPagerAdapter.ARG_SECTION_NUMBER);
        View rootView = inflater.inflate((sectionNumber == 2) ? R.layout.fragment_search : R.layout.fragment_main, container, false);
        if(sectionNumber != 2) {
            TextView textView = (TextView) rootView.findViewById(R.id.section_label);
            textView.setText(getString(R.string.section_format, sectionNumber));
        } else {

            // Its the fragment with search box :
            TextView searchText = (TextView) rootView.findViewById(R.id.search_text);
            ImageView searchIcon = (ImageView)rootView.findViewById(R.id.search_icon);
            searchLayout = (LinearLayout)rootView.findViewById(R.id.search_linear_layout);

            // Need to do transition when clicked on any of the search box elements :
            View.OnClickListener clickListener = new View.OnClickListener(){
                @Override
                public void onClick(View v) {
                    searchLayout.setVisibility(View.INVISIBLE);
                    if(onSearchBoxClick != null)
                        onSearchBoxClick.onClick();
                }
            };
            searchText.setOnClickListener(clickListener);
            searchLayout.setOnClickListener(clickListener);
            searchIcon.setOnClickListener(clickListener);
        }
        return rootView;
    }

    public void showSearchLayout(){
        searchLayout.setVisibility(View.VISIBLE);
    }

    public interface OnSearchBoxClick{
        public void onClick();
    }
}


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.pabhinav.testapp3.MainActivity">

    <android.support.design.widget.TabLayout
        android:layout_marginTop="8dp"
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <!-- Top Search Box -->
    <!-- Only appears when search box is clicked -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:id="@+id/top_search_box"
        android:visibility="invisible"
        android:orientation="horizontal">

        <RelativeLayout
            android:layout_gravity="center"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white">

            <ImageView
                android:gravity = "center"
                android:layout_width="52dp"
                android:paddingLeft="24dp"
                android:paddingRight="8dp"
                android:id="@+id/search_icon"
                android:layout_height="match_parent"
                android:src="@drawable/ic_arrow_back_black_24dp"/>

            <EditText
                android:layout_toEndOf="@+id/search_icon"
                android:hint="@string/search_soundcloud"
                android:textSize="18sp"
                android:background="@android:color/transparent"
                android:textColorHint="#B3B3B3"
                android:layout_margin="4dp"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </RelativeLayout>

    </LinearLayout>

    <!-- Dummy container for search box -->
    <!-- This will do transition from its location to top_search_box location -->
    <RelativeLayout
        android:id="@+id/dummy_search_box"
        android:layout_width="match_parent"
        android:layout_below="@+id/tabs"
        android:visibility="invisible"
        android:layout_height="wrap_content"
        android:padding="16dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="56dp"
            android:id="@+id/search_linear_layout_dummy"
            android:orientation="horizontal">

            <RelativeLayout
                android:layout_gravity="center"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:background="@android:color/white"
                android:elevation="2dp"
                android:translationZ="2dp">

                <ImageView
                    android:gravity = "center"
                    android:layout_width="20dp"
                    android:layout_marginStart="16dp"
                    android:id="@+id/search_icon_dummy"
                    android:layout_height="match_parent"
                    android:src="@drawable/ic_search_light_black_24dp"/>

                <EditText
                    android:id="@+id/search_edit_text"
                    android:layout_toEndOf="@+id/search_icon_dummy"
                    android:hint="@string/search_soundcloud"
                    android:textSize="16sp"
                    android:background="@android:color/transparent"
                    android:textColorHint="#B3B3B3"
                    android:layout_margin="4dp"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />

            </RelativeLayout>

        </LinearLayout>

    </RelativeLayout>


    <android.support.v4.view.ViewPager
        android:layout_below="@+id/tabs"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


    <!-- Dummy overlay over whole page, More things can be added like listview
         which displays result of searched text -->
    <View
        android:id="@+id/overlay_whole_page"
        android:layout_below="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"
        android:background="#72000000" />

    <!-- Dummy shadow below tablayout -->
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_below="@+id/tabs"
        android:background="#42000000" />



</RelativeLayout>

fragment 搜索.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.pabhinav.testapp3.MainActivity$PlaceholderFragment">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:id="@+id/search_linear_layout"
        android:orientation="horizontal">

        <RelativeLayout
            android:layout_gravity="center"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="5dp"
            android:background="@android:color/white"
            android:elevation="2dp"
            android:translationZ="2dp">

            <ImageView
                android:gravity = "center"
                android:layout_width="20dp"
                android:layout_marginStart="16dp"
                android:id="@+id/search_icon"
                android:layout_height="match_parent"
                android:src="@drawable/ic_search_light_black_24dp"/>

            <TextView
                android:id="@+id/search_text"
                android:layout_toEndOf="@+id/search_icon"
                android:text="@string/search_soundcloud"
                android:gravity="center_vertical"
                android:textColor="#B3B3B3"
                android:textSize="16sp"
                android:layout_margin="4dp"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </RelativeLayout>

    </LinearLayout>

    <TextView
        android:id="@+id/suggested_stations"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="56dp"
        android:textSize="18sp"
        android:layout_below="@+id/search_linear_layout"
        android:text = "@string/suggested_stations"/>

    <LinearLayout
        android:layout_below="@+id/suggested_stations"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="0dp"
            android:layout_height="240dp"
            android:src="@drawable/image_1"
            android:layout_weight="1"/>

        <ImageView
            android:layout_marginStart="16dp"
            android:layout_width="0dp"
            android:layout_height="240dp"
            android:src="@drawable/image_2"
            android:layout_weight="1"/>

    </LinearLayout>

</RelativeLayout>


从这里下载整个项目:https://drive.google.com/file/d/0B_Mi44NWLWmyNFNkeHJ6cVBLTTg/view?usp=sharing

希望对您有所帮助!

关于android - 如何在 android 上的选项卡布局上动画覆盖编辑框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40409520/

有关android - 如何在 android 上的选项卡布局上动画覆盖编辑框?的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  3. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  5. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  6. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  7. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  8. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  9. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  10. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

随机推荐