Marquee effect for Linear Layout Marquee effect for Linear Layout android android

Marquee effect for Linear Layout


It can be accomplished using Recycleview and a autoscroll runnable .adding the code snippet here

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. */@Overridepublic 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;@Overridepublic 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;}@Overridepublic void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {}@Overridepublic int getItemCount() {    // 1 for header and 1 for footer    return 4 + 1 + 1;}@Overridepublic 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 holderpublic 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 holderpublic 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 Activity's Layout file(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. Adapter's Layout File(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>

increase or decrease pixelsToMove, this variables value to change the speed


You can solve this using a library, MarqueeView which I have been using for some time and its works great. Here is the link for it.

Usage

In 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>

In 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();            }        });

Please check this sample project for more help.

I would suggest you to use a single TextView inside the MarqueeView and combine both "percentage" and "data" into it.

You can absolutely customize the text size, font style, color, etc attributes of parts of a TextView using Spannable.

Here is a quick little example for you,

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);

You can obviously customize it the way you want to give the percentage and the data a different look in a single TextView only.

You can also display images inside a TextView any where you want using ImageSpan,

Here is a quick example for it,

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

Just ensure that you use correct index positions otherwise you will end up with an StringIndexOutOfBoundsException.