保存本地文件以本地方式做出反应

时间:2019-03-31 11:50:24

标签: react-native

我正在使用React Native创建本地音乐播放器,Google在Android或ios上播放音乐,而其他本地音乐播放器通常不会花时间在用户的手机上加载音乐,我正在使用{{3} }将音乐加载到用户的手机上,然后将其以滚动视图显示,音乐需要花费时间才能加载,并且还需要花费渲染时间,有没有一种方法可以从用户的手机加载一次音乐,然后应用程序被重新加载,它不必再次加载音乐,它已经存在,因此该应用程序将仅检查是否有新音乐和旧音乐。 这是我的下面的代码

 import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
Image,
Dimensions,
StatusBar,
ScrollView,
View,
DeviceEventEmitter,
FlatList,
ActivityIndicator
} from 'react-native';


 import Splash from './components/Splash';
    import Home from './components/Home';
    import MusicFiles from 'react-native-get-music-files';
    import Permissions from 'react-native-permissions';
const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
  android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

export default class App extends Component{
    millisToMinutesAndSeconds(millis) {
        var minutes = Math.floor(millis / 60000);
        var seconds = ((millis % 60000) / 1000).toFixed(0);
        return (seconds == 60 ? (minutes+1) + ":00" : minutes + ":" + (seconds < 10 ? "0" : "") + seconds);
      }
        componentDidMount() {
            this.setState({loaded: false});
            Permissions.request('storage').then(response => {
              this.setState({ photoPermission: response })
            })
            MusicFiles.getAll({
                id : true,
                blured : false,
                artist : true,
                duration : true, //default : true
                cover : true, //default : true,
                title : true,
                cover : true,
                batchNumber : 1, //get 5 songs per batch
                minimumSongDuration : 10000, //in miliseconds,
                fields : ['title','artwork','duration','artist','genre','lyrics','albumTitle']
            });

           }
           componentWillMount() {
            DeviceEventEmitter.addListener(
                'onBatchReceived',
                (params) => {
                    this.setState({songs : [
                        ...this.state.songs,
                        ...params.batch
                    ]}, this.setState({loaded: true}));
                }
            )

        }
    constructor(props) {
        super(props);
        this.state = {
            timePassed: false,
            photoPermission: '',
            songs: [], 
            loaded: true,
            loading: false
        };
    }
    render() {
    if (!this.state.loaded) {
        return (
            <Splash/>
           );
    } else {
        return (
            <View style={styles.linearGradient}>
            <Home songs={this.state.songs}/>
            </View>
        );

    }
    }
    }

    Home.js
    render() { 
        const lyrics = this.props.songs.map((song, index) =>
        <View style={styles.musicBox} key={index}>
        <View style={{width: 57, height: 59, borderRadius: 9, marginLeft: 15}}>
         <Image resizeMode="contain"
         style={{alignSelf: 'center', borderRadius: 9, width: 57, height: 59}}
          source={{uri: song.cover}}/>
          </View>
         <View style={styles.TextBox}>
          <Text 
          numberOfLines={1} 
          style={{fontFamily: 'nexaBold', fontSize: 20, color: 'white', flex: 1}}>
              {song.title}
          </Text>
          <View style={{flexDirection: 'row', }}>
          <Text 
          numberOfLines={1} 
          style={{fontFamily: 'nexaLight', fontSize: 10, color: '#917D7D', 
          marginRight: 5, }}>
              {song.author}
          </Text>
          <View style={{alignSelf:'center',width: 2, height: 2, borderRadius: 1, backgroundColor: '#917D7D',marginRight: 5}}>

          </View>
          <Text style={{fontFamily: 'nexaLight', fontSize: 10, color: '#917D7D'}}>
              {this.millisToMinutesAndSeconds(song.duration)}
          </Text></View>
         </View>
        </View>         
        );

        const music = 
            <ScrollView overScrollMode={'never'} keyboardShouldPersistTaps='always'>
            {lyrics}</ScrollView>;
        const shadowOpt = {
            color: "#000",
            border: 12,
            opacity: '0.08',
            radius: 12,
            x: 0,
            y: 1,
        };          
         return (
            <View style={{flex: 1}}>
            <View style={styles.linearGradient}>                                      
                {music}
                </View>
            </View>
        );
        }

1 个答案:

答案 0 :(得分:2)

我用过react-native-get-music-files,它的运行速度很慢。

您可以使用reduxredux-persist来缓存和加载文件,而不是每次用户打开应用程序时都扫描手机。

编辑

获取媒体的功能。您需要首先请求访问外部存储(Android)的权限。

async function getAssets() {
    try {
        let fetchedFiles = await MusicFiles.getAll({ 
            blured : false,
            artist : true,
            duration : true,
            genre : false,
            title : true,
            cover : true,
            album: true
        });
        return fetchedFiles;
    } catch (e) {
        getAssets();
    }
};

获取媒体文件后,您可以对其进行一点清理,然后将其分发给reducer,使其成为状态的一部分。

dispatch({ type: 'get_media_success', payload: mediaAssets});

这些媒体文件将在应用重启之间自动保留。您只需要使用redux-persist正确配置商店即可。

我的商店index.js:

import { createStore, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { persistStore, persistReducer } from 'redux-persist';
import { AsyncStorage } from 'react-native';
import reducers from '../Reducers';

const persistConfig = {
    key: 'root',
    storage: AsyncStorage,
    blacklist: ['search'] //Anything you don't want to persist goes here
};

const persistedReducer = persistReducer(persistConfig, reducers);

export const store = createStore(persistedReducer, {}, compose(applyMiddleware(thunk)));
export const persistor = persistStore(store);

然后导入persister并按如下方式存储和包装您的根组件:

<PersistGate loading={null} persistor={persistor}>
     <Provider store={store}>
         <RootComponent/>
     </Provider>
</PersistGate>