线性布局的选框效果

时间:2015-07-17 08:36:11

标签: android android-linearlayout android-animation horizontalscrollview marquee

我正在尝试对布局实施选框效果,以帮助它从右侧内侧向左侧内侧滚动/动画,就像自动收报机视图一样。

通过以下两个链接,您可以获得更多知识,就像股票市场通过以循环常量方式显示值来更新用户一样。

1)http://www.sify.com/finance/livemarkets/

2)http://terminal.moneycontrol.com/index.php?wl=indices

为此,我已经实现了以下代码,使其有些类似。

public class HorizonalSlideActivity extends Activity
{
    private LinearLayout horizontalOuterLayout;
    private HorizontalScrollView horizontalScrollview;
    private int scrollMax;
    private int scrollPos = 0;
    private TimerTask scrollerSchedule;
    private Timer scrollTimer = null;
    private ScrollAdapter adapter = null;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.horizontal_layout);

        adapter = new ScrollAdapter(HorizonalSlideActivity.this);

        horizontalScrollview = (HorizontalScrollView) findViewById(R.id.horiztonal_scrollview_id);
        horizontalScrollview.setOnTouchListener(new OnTouchListener()
        {
            @Override
            public boolean onTouch(View v, MotionEvent event)
            {
                return false;
            }
        });
        horizontalOuterLayout = (LinearLayout) findViewById(R.id.horiztonal_outer_layout_id);
        horizontalTextView = (TextView) findViewById(R.id.horizontal_textview_id);
        horizontalScrollview.setHorizontalScrollBarEnabled(false);

        addData();


        ViewTreeObserver vto = horizontalOuterLayout.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener()
        {
            @Override
            public void onGlobalLayout()
            {
                horizontalOuterLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                getScrollMaxAmount();
                startAutoScrolling();
            }
        }); 
    }

    private void addData()
    {
        for (int i = 0; i < adapter.getCount(); i++)
        {
            View convertView = adapter.getView(i, null, null);
            horizontalOuterLayout.addView(convertView);
        }
    }

    public void getScrollMaxAmount()
    {
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int width = size.x;
        Log.e("getScrollMaxAmount", "getWidth == "+width);
        Log.e("getScrollMaxAmount", "getMeasuredWidth == "+horizontalOuterLayout.getMeasuredWidth());
        int actualWidth = (horizontalOuterLayout.getMeasuredWidth() - width);
        Log.e("getScrollMaxAmount", "actualWidth == "+actualWidth);
        scrollMax = actualWidth;
        Log.e("getScrollMaxAmount", "scrollMax == "+scrollMax);
    }

    public void startAutoScrolling()
    {
        if (scrollTimer == null)
        {
            scrollTimer = new Timer();
            final Runnable TimerTick = new Runnable()
            {
                public void run()
                {
                    moveScrollView();
                }
            };

            if (scrollerSchedule != null)
            {
                scrollerSchedule.cancel();
                scrollerSchedule = null;
            }
            scrollerSchedule = new TimerTask()
            {
                @Override
                public void run()
                {
                    runOnUiThread(TimerTick);
                }
            };

            scrollTimer.schedule(scrollerSchedule, 3000, 30);
        }
    }

    public void moveScrollView()
    {
        Log.e("moveScrollView", "scrollMax == "+scrollMax);
        scrollPos = (int) (horizontalScrollview.getScrollX() + 1.0);
        Log.e("moveScrollView", "scrollPos == "+scrollPos);
        if (scrollPos >= scrollMax)
        {
            scrollPos = 0;
        }
        horizontalScrollview.scrollTo(scrollPos, 0);
    }

    public void stopAutoScrolling()
    {
        if (scrollTimer != null)
        {
            scrollTimer.cancel();
            scrollTimer = null;
        }
    }

    public void onBackPressed()
    {
        super.onBackPressed();
        finish();
    }

    public void onPause()
    {
        super.onPause();
        finish();
    }

    public void onDestroy()
    {
        clearTimerTaks(scrollerSchedule);
        clearTimers(scrollTimer);

        scrollerSchedule = null;
        scrollTimer = null;
        super.onDestroy();
    }

    private void clearTimers(Timer timer)
    {
        if (timer != null)
        {
            timer.cancel();
            timer = null;
        }
    }

    private void clearTimerTaks(TimerTask timerTask)
    {
        if (timerTask != null)
        {
            timerTask.cancel();
            timerTask = null;
        }
    }
}

以下是此文件的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <HorizontalScrollView
        android:id="@+id/horiztonal_scrollview_id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fadingEdge="none" >

        <LinearLayout
            android:id="@+id/horiztonal_outer_layout_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#ffffff"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingBottom="5dip"
            android:paddingTop="5dip" >
        </LinearLayout>
    </HorizontalScrollView>

</LinearLayout>

显示数据的适配器类:

public class ScrollAdapter extends BaseAdapter
{

    private Context context;

    public ScrollAdapter(Context context)
    {
        this.context = context;
    }

    @Override
    public int getCount()
    {
        return 10;
    }

    @Override
    public Object getItem(int position)
    {
        return position;
    }

    @Override
    public long getItemId(int position)
    {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        convertView = inflater.inflate(R.layout.scroll_child, null);
        return convertView;
    }

}

及其xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/txtPercent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:paddingLeft="30dp"
        android:paddingRight="30dp"
        android:text="0.14%" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="@android:color/white" />

    <TextView
        android:id="@+id/txtData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:paddingLeft="30dp"
        android:paddingRight="30dp"
        android:text="data" />

</LinearLayout>

通过实施这一点,我有点接近但无法做出所需的。请帮我把它做成循环而没有任何中断,并在最后一个数据从左侧向内移动后重新开始滚动。

这是期望的结果:

enter image description here

我也检查了this link,它给出了所需的滚动效果,但没有显示整个数据,它只显示3到4个视图但是你可以看到我在适配器类中添加了10个数据。

任何形式的帮助都会很明显。

提前致谢。

2 个答案:

答案 0 :(得分:10)

可以使用Recycleview和autoscroll runnable来完成。 在此处添加代码段

<强> 1。 MainActivity(MarqueeViewSample.java)

package com.test.mo.test;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;

/**
* Created by jovin.pj on 29-07-2015.
*/
public class MarqueeViewSample extends Activity {

private final Runnable SCROLLING_RUNNABLE = new Runnable() {

    @Override
    public void run() {
        final int duration = 10;
        final int pixelsToMove = 10;
        marqueList.smoothScrollBy(pixelsToMove, 0);
        mHandler.postDelayed(this, duration);
    }
};

private final Handler mHandler = new Handler(Looper.getMainLooper());
private RecyclerView marqueList;
//private boolean loading = true;
private boolean foundTotalPixel = true;
private int pastVisiblesItems, visibleItemCount, totalItemCount;
private int totalMovedPixel;
private int totalPixel;

/**
 * Called when the activity is first created.
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    marqueList = (RecyclerView) findViewById(R.id.marqueList);
    final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
    marqueList.setLayoutManager(layoutManager);
    marqueList.setAdapter(new ScrollAdapter());

    marqueList.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            totalMovedPixel = totalMovedPixel + dx;
            visibleItemCount = layoutManager.getChildCount();
            totalItemCount = layoutManager.getItemCount();
            pastVisiblesItems = layoutManager.findFirstVisibleItemPosition();
            if (foundTotalPixel) {
                if (totalItemCount > 2) {
                    View headerView = layoutManager.getChildAt(0);
                    View itemView = layoutManager.getChildAt(1);

                    if (itemView != null && headerView != null) {
                        /*total visible scrolling part is total pixel's of total item's count and header view*/
                        totalPixel = /*-c.getTop() +*/ ((totalItemCount - 2) * itemView.getWidth()) + (1 * headerView.getWidth());
                        Log.v("...", "Total pixel x!" + totalPixel);
                        foundTotalPixel = false;
                    }
                }
            }

            //if (loading) {
            //if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
            if (!foundTotalPixel && totalMovedPixel >= totalPixel) {
                // loading = false;
                Log.v("...", "Last Item Wow !");
                Log.v("...", "totalMovedPixel !" + totalMovedPixel);

                // use this to turn auto-scrolling off:
                //mHandler.removeCallbacks(SCROLLING_RUNNABLE);
                marqueList.setAdapter(null);
                marqueList.setAdapter(new ScrollAdapter());
                pastVisiblesItems = visibleItemCount = totalItemCount = 0;
                totalMovedPixel = 0;

            }
        }
        // }
    });
    // use this to turn auto-scrolling on:
    mHandler.post(SCROLLING_RUNNABLE);
 }
}

<强> 2。查看SampleAdapter(ScrollAdapter.java)

package com.test.mo.test;

import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

/**
 * Created by jovin.pj on 29-07-2015.
 */
public class ScrollAdapter extends  RecyclerView.Adapter<RecyclerView.ViewHolder> {

private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private static final int TYPE_FOOTER = 2;


@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    RecyclerView.ViewHolder viewHolder = null;
    if (viewType == TYPE_ITEM) {
        //inflate your layout and pass it to view holder
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.scroll_child, parent, false);
        viewHolder = new ViewHolderItem(view);
    } else if (viewType == TYPE_HEADER || viewType == TYPE_FOOTER) {
        //inflate your layout and pass it to view holder
        //View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_footer, parent, false);
        View view = new View(parent.getContext());
        DisplayMetrics metrics = parent.getContext().getResources().getDisplayMetrics();
        int width = metrics.widthPixels;
        view.setLayoutParams(new LinearLayout.LayoutParams(width, LinearLayout.LayoutParams.WRAP_CONTENT));
        viewHolder = new ViewHolderHeaderOrFooter(view);
    }

    return viewHolder;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

}

@Override
public int getItemCount() {
    // 1 for header and 1 for footer
    return 4 + 1 + 1;
}

@Override
public int getItemViewType(int position) {
    if (isPositionHeader(position))
        return TYPE_HEADER;
    else if (isPositionFooter(position))
        return TYPE_FOOTER;
    return TYPE_ITEM;
}


private boolean isPositionHeader(int position) {
    return position == 0;
}

private boolean isPositionFooter(int position) {
    return position == getItemCount() - 1;
}


// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolderItem extends RecyclerView.ViewHolder {
    // each data item is just a string in this case
    public View mView;
    public ViewHolderItem(View v) {
        super(v);
        mView = v;
    }
}

// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolderHeaderOrFooter extends RecyclerView.ViewHolder {
    // each data item is just a string in this case
    public View mView;
    public ViewHolderHeaderOrFooter(View v) {
        super(v);
        mView = v;
    }
 }
}

第3。主要活动的布局文件(main.xml)

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical">


 <android.support.v7.widget.RecyclerView
    android:id="@+id/marqueList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:clipToPadding="false" />


</LinearLayout>

<强> 4。适配器的布局文件(scroll_child.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:orientation="vertical" >

<TextView
    android:id="@+id/txtPercent"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:paddingLeft="30dp"
    android:paddingRight="30dp"
    android:text="0.14%" />

<View
    android:layout_width="match_parent"
    android:layout_height="1px"
    android:background="@android:color/darker_gray" />

<TextView
    android:id="@+id/txtData"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:paddingLeft="30dp"
    android:paddingRight="30dp"
    android:text="data" />

</LinearLayout>

增加或减少pixelsToMove,这个变量值改变速度

答案 1 :(得分:1)

您可以使用我已经使用了一段时间的 MarqueeView 库来解决这个问题。 Here是它的链接。

用法

XML 中,

<asia.ivity.android.marqueeview.MarqueeView
        android:id="@+id/marqueeView150"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        marquee:speed="5"
        marquee:pause="1000"
        marquee:autoStart="true"
        >

        <TextView
            android:id="@+id/textView2"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do."
            android:textSize="20sp"
            android:textStyle="bold"
            android:singleLine="true"
            android:ellipsize="end"
            tools:ignore="HardcodedText"/>
    </asia.ivity.android.marqueeview.MarqueeView>

Java

final MarqueeView mv = (MarqueeView) findViewById(R.id.marqueeView100);
        mv.setPauseBetweenAnimations(500);
        mv.setSpeed(10);
        getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                mv.startMarquee();
            }
        });

请查看此sample项目以获取更多帮助。

我建议你在TextView内使用一个MarqueeView并将两者结合起来&#34;百分比&#34;和&#34;数据&#34;进入它。

您可以使用Spannable完全自定义TextView各部分的文字大小,字体样式,颜色等属性。

这是一个快速的小例子,

Spannable spn = (Spannable) tv3.getText();
        spn.setSpan(new BackgroundColorSpan(Color.RED), 0, 7,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        spn.setSpan(new StyleSpan(android.graphics.Typeface.BOLD_ITALIC),0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

您显然可以按照您希望的方式自定义它,只在单个TextView中为百分比和数据提供不同的外观。

您还可以使用ImageSpan

在TextView中的任何位置显示图像

以下是一个简单的例子,

ImageSpan is = new ImageSpan(context, resId);
text.setSpan(is, index, index + strLength, 0);

确保使用正确的索引位置,否则最终会得到StringIndexOutOfBoundsException