あなたは、どちらかの状況に遭遇したかもしれません。
あなたの画面は平らで未完成のようで、背景やボタンが実際の製品のように感じたいと思ったり、既に React Native のグラデーションを追加したが、設定の迷いの中に囚われているかもしれません。半分の例は Expo を使用し、もう半分はネイティブ プロジェクトを使用しているため、設定が難しくなっています。
That split is where most tutorials stop being useful. The component API is simple. The environment choice isn’t. A clean linear gradient React Native setup depends less on the colors プロパティとその他の情報は、Expo管理ワークフロー内にいるか、ネイティブリンク、ポッド、テストモックを自分で扱っているかによって異なります。
目次
- なぜReact Nativeアプリにグラデーションが必要なのか
- ExpoとBare React Nativeのセットアップの選択
- UI要素のためのグラデーション技術の基本
- アニメーションでグラデーションを実現する
- パフォーマンス、アクセシビリティ、プラットフォームの特徴
- トラブルシューティングと最終的なベストプラクティス
あなたのReact Nativeアプリにグラデーションが必要な理由
モバイルUIの多くが同じ理由で失敗する。レイアウトは問題ない、スペースは問題ない、フォントは可愛いが、画面はまだ死んでいる。固形色の塗りつぶしは、残りの視覚システムが多くの作業をしている場合を除いて、すべてのプレースホルダーに似ているように見える。
A リアルタイム グラデーション React Native コンポーネントはそれを非常に少ない code で修正します。深みを加え、セクション間の区別を生み出し、高優先度の要素に明確な視覚的重みを与えます。良質なグラデーション背景は、ログイン画面が意図的であるように感じさせることができます。良質なグラデーションバトンは、重い影や過度に明るいボーダーに頼ることなく、主なアクションを明確に示すことができます。
By 2019年、expo-linear-gradientとreact-native-linear-gradientはReact Nativeプロジェクトの42%以上で登場しました。, は、グラデーションが特殊な機能ではなく、標準的なUIツールとしての役割を果たしていることを示しています。 それは、実用的なアプリケーションで標準的なツールとして使用されていることを意味します。 React Native の線形グラデーション採用レポート.
何のグラデーションがうまく機能するか
- Create depth: 背景が平坦で一枚の画面は未完成のように見えることがある。上から下への微妙な合成は表面が層化されたもののように感じる。
- ガイドの注意: 主なCTA、オンボーディングカード、ヘッドラインヘッダーは、視覚的なノイズを追加せずに目立つ。
- 画像資産を置き換えます。 多くの場合、グラデーションは、背景画像を追加しなくても、ポリッシュを与えることができます。
実用的なルール: グラデーションは、階層が重要な場合に使用する。背景、ヘッドラインカード、CTA表面、メディアオーバーレイが最も利益を受けます。フォームフィールド、密集したリスト、ボディーコピー容器は通常、ありません。
また、製品設計の観点もあります。プラットフォームをまたがるチームは、既にインターフェイスを一貫させようとしている時間を費やしています。そうしたスタックがあれば、これらの クロスプラットフォームのUIとUXの慣習 モバイルアプリの
ラインナップが同じ考え方に沿っています: アセットを少なくし、再利用可能な表面を増やし、スクリーンをまたがる視覚システムを維持する。
This is the fork that causes most of the pain. The rendering API feels almost identical in both libraries, but setup isn’t.
これが最も多くの痛みを引き起こす分岐です。レンダリングの__CAPGO_KEEP_0__は、両方のライブラリでほぼ同じに感じられますが、セットアップはありません。 expo-linear-gradientあなたがExpo管理アプリにいる場合、を使用してください。 react-native-linear-gradient. その線をぼかすことは、きちんと何をしているのかわかっている場合に限ります。

Expo設定
Expoはよりスムーズなパスです。インストールは簡単で、バージョンマッチングは自動で行われ、ネイティブリンクについて考える必要がありません。
インストール方法は次のとおりです。
npx expo install expo-linear-gradient
使用方法は次のとおりです。
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
export default function App() {
return (
<LinearGradient
colors={['#0f172a', '#1d4ed8']}
style={styles.container}
>
<Text style={styles.text}>Hello gradient</Text>
</LinearGradient>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
color: '#fff',
fontSize: 24,
fontWeight: '700',
},
});
Expoは、高速なセットアップ、正常なデフォルト、ネイティブエッジの少ないオプションが必要な場合に最適な選択です。そのため、チームは通常、Expoの高度なワークフローを探索することになり、カスタムネイティブ機能のためにExpo開発クライアントを使用します。 Expo開発クライアントは、カスタムネイティブ機能のために使用される場合に限ります。 バレなReact Native設定
バレなReact Nativeは、直接ネイティブモジュールにアクセスできるようにしますが、粗いエッジはあなたが所有することになります。
パッケージをインストールするには
__CAPGO_KEEP_0__
npm install react-native-linear-gradient
iOS用の場合、Podsをインストールしてください:
cd ios && pod install
基本的な使用方法:
import React from 'react';
import { StyleSheet, Text } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
export default function App() {
return (
<LinearGradient
colors={['#111827', '#7c3aed']}
style={styles.container}
>
<Text style={styles.text}>Hello gradient</Text>
</LinearGradient>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
color: '#fff',
fontSize: 24,
fontWeight: '700',
},
});
通常、裸のプロジェクトが壊れる
ほとんどのチュートリアルでは、テストとネイティブのセットアップが欠けていることが多い。 Stack Overflowの議論のまとめによると, 2024年から2025年の間に、このトピックに関するStack Overflowのスレッドの68%が、裸のReact Nativeのセットアップにおけるネイティブモジュールの失敗を含んでいます。、そして同じソースは、JestのモッキングとiOSのCocoaPodsの競合についての繰り返し問題を指摘しています。
Jestを裸のアプリで使用する場合、モックを明示的に追加してください:
// jest.setup.js
import mockRNLinearGradient from 'react-native-linear-gradient/jest/linear-gradient-mock';
jest.mock('react-native-linear-gradient', () => mockRNLinearGradient);
そして、Jestの設定ファイルにそのセットアップファイルを参照してください:
module.exports = {
preset: 'react-native',
setupFiles: ['<rootDir>/jest.setup.js'],
};
裸のReact Nativeはグレードのためにうまく機能しますが、不完全なセットアップを許すことはありません。ほとんどの失敗は視覚的なバグではありません。リンク、Pods、またはテスト環境の問題です。
実践的な決定表:
| プロジェクトのタイプ | ライブラリ | 最適なフィット |
|---|---|---|
| エクスポマネージドアプリ | expo-linear-gradient |
最速のパス、最小のセットアップ |
| バーレイナティブアプリ | react-native-linear-gradient |
フルネイティブコントロール |
| バーレアプリケーション | react-native-linear-gradient +モック |
テストの安定性を維持するために必要 |
UI要素のコアグレードテクニック
同じ小さなグラデーションパターンを繰り返し使用するのが一般的なアプローチです。背景。ボタン。ヘッダー。3つが固体の場合、多くの画面で再利用できます。

有用なメンタルモデルは次のようになっています。
colorsグラデーションパレットを制御するstartとend方向制御locationsトランジションが発生する場所を制御します。
このスプラッシュまたはオンボーディングエントリ画面がグラデーションを使用している場合、それはこの説明されたより広い起動シーケンスパターンと自然にマッチします。 React Native スプラッシュ画面ガイド.
フルスクリーン背景グラデーション
最も単純で最も再利用可能なパターンです。
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
// For bare RN, switch to:
// import LinearGradient from 'react-native-linear-gradient';
export default function WelcomeScreen() {
return (
<LinearGradient
colors={['#0f172a', '#1e293b', '#2563eb']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={styles.container}
>
<View style={styles.content}>
<Text style={styles.title}>Welcome back</Text>
<Text style={styles.subtitle}>Your workspace is ready.</Text>
</View>
</LinearGradient>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
content: {
flex: 1,
justifyContent: 'center',
paddingHorizontal: 24,
},
title: {
color: '#fff',
fontSize: 32,
fontWeight: '800',
marginBottom: 8,
},
subtitle: {
color: 'rgba(255,255,255,0.8)',
fontSize: 16,
},
});
線形グラデーションは、垂直のデフォルトのものよりもダイナミックに感じられることが多い。なぜなら start={{ x: 0, y: 0 }} と end={{ x: 1, y: 1 }} 画面が主に装飾的な場合、デフォルトではこのスタイルを使用します。
色を孤立して選択しないでください。実際のテキスト、アイコン、ステータスバーのスタイルの後ろでテストしてください。Figmaで見栄えのよいパレットは、コンテンツが上に乗ったときに即座に失敗します。
グラデーションでボタンがまだボタンとして振る舞う
ここで一般的な間違いは、グラデーションにタッチの挙動を直接付けて、無効化状態、押下反応、パディングの統一性を忘れてしまうことです。ボタンは意味を保ち、グラデーションは視覚的なレイヤーとして残してください。
import React from 'react';
import {
Pressable,
StyleSheet,
Text,
ViewStyle,
StyleProp,
} from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
type Props = {
title: string;
onPress: () => void;
disabled?: boolean;
style?: StyleProp<ViewStyle>;
};
export function GradientButton({
title,
onPress,
disabled = false,
style,
}: Props) {
return (
<Pressable onPress={onPress} disabled={disabled} style={style}>
{({ pressed }) => (
<LinearGradient
colors={
disabled
? ['#94a3b8', '#94a3b8']
: pressed
? ['#7c3aed', '#2563eb']
: ['#8b5cf6', '#3b82f6']
}
start={{ x: 0, y: 0.5 }}
end={{ x: 1, y: 0.5 }}
style={styles.button}
>
<Text style={styles.label}>{title}</Text>
</LinearGradient>
)}
</Pressable>
);
}
const styles = StyleSheet.create({
button: {
minHeight: 52,
borderRadius: 14,
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 20,
},
label: {
color: '#fff',
fontSize: 16,
fontWeight: '700',
},
});
ボタンでは、水平方向のグラデーションが斜めのものよりも読みやすいことが多いです。ラベルは安定し、コントロールが傾いたように感じさせないからです。
グラデーションでテキストをマスクする
これはセットの中で最も派手なパターンであり、制限を保ったままにすると有用です。ヒーロータイトル、アップグレードバナー、空の状態のヘッダーは適切ですが、段落テキストではありません。
必要なのは @react-native-masked-view/masked-view.
npm install @react-native-masked-view/masked-view
次にテキストマスクを作成してください:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import MaskedView from '@react-native-masked-view/masked-view';
import { LinearGradient } from 'expo-linear-gradient';
export default function GradientHeadline() {
return (
<View style={styles.container}>
<MaskedView
maskElement={
<View style={styles.maskWrapper}>
<Text style={styles.title}>Premium analytics</Text>
</View>
}
>
<LinearGradient
colors={['#22c55e', '#06b6d4', '#3b82f6']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
locations={[0, 0.5, 1]}
>
<Text style={[styles.title, styles.hiddenText]}>Premium analytics</Text>
</LinearGradient>
</MaskedView>
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 24,
},
maskWrapper: {
backgroundColor: 'transparent',
},
title: {
fontSize: 34,
fontWeight: '800',
letterSpacing: -1,
},
hiddenText: {
opacity: 0,
},
});
locations 色の占める視覚的なスペースが異なる場合、色の数を減らすことで混濁感を解消できます。色の停止を調整するのではなく、まずは色の数を減らしてみましょう。
グラデーションをアニメーションで活性化する
静的なグラデーションはポリッシュを与えます。アニメーションでグラデーションを活性化すると、フィードバックが得られます。
最も実用的な使い方は、派手な背景ではありません。シャイムローダーです。ユーザーにアプリが活性化していることを示し、データが流れてきていることを示し、表示されているレイアウトが意図的なものであることを示します。

Shimmerコンポーネントも他の動きのパターンと相性が良い。アプリがすでにアニメーションアイコンやローダーを使用している場合、この Lottie in React Nativeガイド は、グラデーションシャイマーが十分か、より豊かなアニメーションアセットが必要かを判断するのに役立ちます。
動きのあるローダーが本来のネイティブ感を与える
最も信頼できるバージョンは、 react-native-reanimated グラデーションを動かすために、クリップされたプレースホルダーの横を動かすだけです。
Reanimatedをインストールするには、まだアプリにない場合は、まずアプリに追加してください。次に、 overflow: 'hidden'を使用してラッパーを作成します。内部に、左から右にグラデーションレイヤーをアニメーション化します。
import React, { useEffect } from 'react';
import { StyleSheet, View, ViewStyle, StyleProp } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import Animated, {
useAnimatedStyle,
useSharedValue,
withRepeat,
withTiming,
Easing,
} from 'react-native-reanimated';
const AnimatedView = Animated.createAnimatedComponent(View);
type Props = {
width?: number | string;
height?: number;
borderRadius?: number;
style?: StyleProp<ViewStyle>;
};
export function ShimmerPlaceholder({
width = '100%',
height = 16,
borderRadius = 8,
style,
}: Props) {
const translateX = useSharedValue(-220);
useEffect(() => {
translateX.value = withRepeat(
withTiming(220, {
duration: 1200,
easing: Easing.linear,
}),
-1,
false
);
}, [translateX]);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: translateX.value }],
}));
return (
<View
style={[
styles.container,
{ width, height, borderRadius },
style,
]}
>
<AnimatedView style={[styles.shimmer, animatedStyle]}>
<LinearGradient
colors={['rgba(255,255,255,0)', 'rgba(255,255,255,0.35)', 'rgba(255,255,255,0)']}
start={{ x: 0, y: 0.5 }}
end={{ x: 1, y: 0.5 }}
style={styles.gradient}
/>
</AnimatedView>
</View>
);
}
const styles = StyleSheet.create({
container: {
overflow: 'hidden',
backgroundColor: '#e5e7eb',
},
shimmer: {
...StyleSheet.absoluteFillObject,
width: 220,
},
gradient: {
flex: 1,
},
});
この方法が機能するのは、グラデーション定義自体をアニメーション化するのではなく、静的プレースホルダーの横を動かすグラデーションレイヤーをアニメーション化しているからです。そうすることで、よりシンプルで論理的に理解しやすく、通常はデバイス間で安定性が高くなります。
実際の効果の視覚的なウォークスルーはこちらです:
アニメーションコンポーネント
A few implementation notes matter:
- Clipping を使用します: 親要素が必要です
overflow: 'hidden', または、シェイムは丸い角の外側に流れ出てしまいます。 - バンドの幅を小さくしましょう: 小さなアニメーションレイヤーは、全体の表面をアニメーションするよりも調整が容易です。
- ベースカラーを画面に合わせましょう: スケルトンローダーは、周囲のレイアウトに合うようにデザインする必要があります。別のウィジェットのように見えると良くありません。
アニメーショングラデーションは、ユーザーがほとんど気づかないようにすることが最善です。シェイムが画面上で最も目立つものになっていると、もう少ししていることになります。
パフォーマンス、アクセシビリティ、プラットフォームの特性
デモ画面から実際のアプリにグラデーションを移すと、懸念事項が変わります。code はまだシンプルに見えますが、レンダリングの挙動、読みやすさ、プラットフォームの統一性は、初期の効果よりも重要になります。
アプリのレスポンスをより広く向上させる場合、この モバイルアプリパフォーマンス最適化ガイド 同じ考え方に合致するものがあります: 必要な作業を削減し、実機で測定し、ユーザーが最も見る表面を最適化すること。
パフォーマンスチェックリスト
ネイティブのグラデーションは一般的に効率的ですが、まだ誤用することができます。
- 大きな装飾画像よりもグラデーションを優先すること: 通常、よりきれいに配信し、複数の画面サイズに適応しやすい。
- 重いアニメーションやブルー効果を含む多数のフルスクリーンレイヤーを積み重ねないように: 1 つの背景グラデーションは問題ありません。複数の重なり合った半透明グラデーションにブルー効果を加えたり、重いアニメーションを実行したりすると高価になります。
- 再利用可能なコンポーネントをメモ化する: リスト内でグラデーションカードが使用されている場合、プロパティを安定させて、無関係な親ステートによって再レンダリングされるのを避けます。
良いルールは、グラデーションを構造的なものにし、過剰なものにしないことです。表面を定義するために使用し、密集したフィード内の各行に使用するのではなく。
アクセシビリティチェックリスト
グラデーションは、表面全体でContrastが変化するため、読みやすさを損なう可能性があります。
- テストテキストを最も明るいエリアでテストしてください。 白のテキストが暗いブレンドの向こう側でしか機能しない場合、機能しません。
- 必要に応じてスクリムを追加してください。 背景とテキストの間の微妙な暗いオーバーレイは、パレット全体を変更することよりもよく機能します。
- 大きな表示コピー用にグラデーションテキストを予約してください。 見栄えがいいのはいいですが、小さなラベル、ヘルプテキスト、タスクを完了するのに重要なものなどは避けてください。
グラデーションの最悪のケースのポイントをチェックしてください。最も見栄えの良いものではありません。
プラットフォームの特徴のチェックリスト
iOSとAndroidは通常同じグラデーションをよく表示しますが、完全に一致するわけではありません。
| 問題 | よく役立つもの |
|---|---|
| プラットフォーム間でグラデーションが見え方が異なる | 使用する色の数を減らし、グラデーションの各ステップ間の明度の差を明確にする |
| 丸角のコーナーはグラデーションをクリップしない | Put overflow: 'hidden' コンテナに |
| グラデーションが全く表示されない | 幅、高さ、または flex: 1 最初 |
も確認する
ステータスバーとセーフエリアの扱いも気をつける。シミュレータでバランスがとれたグラデーションは、ノッチが付いたデバイスでは、コンテンツと背景がその余分なスペースを考慮していない場合、上向きに感じられることがある
トラブルシューティングと最終的なベストプラクティス
- プロジェクトノートに残す短いバージョンだ。
expo-linear-gradientExpo管理アプリ用react-native-linear-gradientバレなReact Native用 - グラデーションの目的を意図的に使う 背景、CTA、オーバーレイ、ヘローテキストは強力な使用例
- 方向を意図的に制御する ボタン用に水平、装飾用に斜め、テキスト用にマスクのみ
- コンテンツ用に設計する、空の状態用に設計しない 実際のコピー、アイコン、ステータスバーの処理とテストする
- バレなセットアップをネイティブセットアップと扱う ポッド、リンク、Jestモックは省略できない詳細
3つの共通の失敗が繰り返し発生する
グラデーションが表示されない
原因: コンポーネントには表示サイズがない。
修正: 明示的な高さを与え、または親要素に寸法を指定する。 flex: 1iOS ビルドがインストール後に破損する
原因: Pods がインストールされていなかったり、ネイティブ依存グラフが同期されていなかったりする。
修正:
で実行し、ビルドフォルダをクリーンする必要がある場合はクリーンし、再ビルドする。バーレスプロジェクトでは、パッケージインストールだけでは通常では十分ではない。 pod install ネイティブモジュールエラーでテストが失敗する ios原因: Jest が実際のネイティブモジュールを読もうとしている。
修正:
をモックする
で react-native-linear-gradient を使用する react-native-linear-gradient/jest/linear-gradient-mock Jest セットアップファイル内で。
このガイドの全てのアイデアから1つだけを残すなら、次の1つを残しておけばいい。グラデーション自体は簡単だ。生産用のセットアップは主な努力だ。アプリのアーキテクチャに適したライブラリを選ぶだけで、以降は予測可能になる。
チームがハイブリッドモバイルアプリをリリースし、JavaScript、CSS、コピー、設定、資産の更新をストアのレビュー待たずにプッシュしたい場合 Capgo CapacitorJSとElectronチームに制御されたライブアップデート、ロールアウトチャンネル、ロールバック保護、リリースの可視性を提供するので、展開プロセスをブラックボックスに変えることなく見る価値がある。